C# C中来自另一个线程的事件

C# C中来自另一个线程的事件,c#,mono,gtk#,C#,Mono,Gtk#,我有这样的代码: 我从某人的博客上得到的。它必须对大文件进行排序。 我将其预成型为单独的螺纹: protected virtual void goButton_Clicked (object sender, System.EventArgs e) { FileSort fileSort = new FileSort(fileNameEntry.Text, "./BigFileSorted.dat"); fileSort.SplitProgressChanged += fi

我有这样的代码:

我从某人的博客上得到的。它必须对大文件进行排序。 我将其预成型为单独的螺纹:

    protected virtual void goButton_Clicked (object sender, System.EventArgs e)
{
    FileSort fileSort = new FileSort(fileNameEntry.Text, "./BigFileSorted.dat");
    fileSort.SplitProgressChanged += fileSortProgressSplitting; 
    fileSort.SortChunksProgressChanged += fileSortProgressSorting; 
    fileSort.MergeProgressChanged += fileSortProgressMerging; 

    Thread thread = new Thread(fileSort.Sort);
    thread.Start();
    //fileSort.Sort();
}

protected virtual void fileSortProgressSplitting(FileSort o, double progress)
{
    progressBar.Fraction = progress;
    progressBar.Text = "Splitting...";
}

protected virtual void fileSortProgressSorting(FileSort o, double progress)
{
    progressBar.Fraction = progress;
    progressBar.Text = "Sorting...";
}

protected virtual void fileSortProgressMerging(FileSort o, double progress)
{
    progressBar.Fraction = progress;
    progressBar.Text = "Merging...";

}
对于小文件,一切正常,但对于大约4 gb的大文件,progressBar在拆分步骤中由于某种原因在某个值上停止。但分裂已经结束。这奇怪的原因是什么?
另外,我是在Mono和Gtk上写的。

你不能从非GUI线程触摸GUI对象。结果是不可预测的。有时它会抛出异常,但并非总是如此

相反,使用Invoke或BeginInvoke方法前者更好。像这样:

protected virtual void fileSortProgressSplitting(FileSort o, double progress)
{
    BeginInvoke( new Action( () =>
        {
            progressBar.Fraction = progress;
            progressBar.Text = "Splitting...";
        } );
}

您不能从非GUI线程接触GUI对象。结果是不可预测的。有时它会抛出异常,但并非总是如此

相反,使用Invoke或BeginInvoke方法前者更好。像这样:

protected virtual void fileSortProgressSplitting(FileSort o, double progress)
{
    BeginInvoke( new Action( () =>
        {
            progressBar.Fraction = progress;
            progressBar.Text = "Splitting...";
        } );
}

与winforms一样,Gtk具有线程关联性。您的更新应该发生在主UI循环上。您可以通过以下方式执行此操作:

protected virtual void fileSortProgressMerging(FileSort o, double progress) {
    Gtk.Application.Invoke (delegate {
        progressBar.Fraction = progress;
        progressBar.Text = "Merging...";
    });    
}

另请参见此部分的注释。

与winforms一样,Gtk具有线程关联性。您的更新应该发生在主UI循环上。您可以通过以下方式执行此操作:

protected virtual void fileSortProgressMerging(FileSort o, double progress) {
    Gtk.Application.Invoke (delegate {
        progressBar.Fraction = progress;
        progressBar.Text = "Merging...";
    });    
}

另请参见此注释。

我从某人的博客上获得:-这不是一个令人震惊的指控!可能需要查看int的最大大小,以及.NET中单个对象的最大大小…这些对象刚好捕获事件。进度计算在哪里?我是从某人的博客上得到的:-这不是一个令人震惊的起诉!可能需要查看int的最大大小,以及.NET中单个对象的最大大小…这些对象刚好捕获事件。进度计算在哪里?哦。。。我的错。这个论点仍然适用,不是吗?哦。。。我的错。这个论点仍然适用,不是吗?嗯。。。有趣的我以前从未见过GTK。因此,我们可以由此推断,GTK每个进程只能有一个GUI线程,对吗?说真的,mono人使用老式的委托语法是怎么回事,请阅读lamba表达式。请…嗯。。。有趣的我以前从未见过GTK。因此,我们可以由此推断,GTK每个进程只能有一个GUI线程,对吗?说真的,mono人使用老式的委托语法是怎么回事,请阅读lamba表达式。请