简体   繁体   English

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

[英]Events from another thread in C#

I have a such code: http://pastie.org/1638879 我有这样的代码: http : //pastie.org/1638879

I got it from someone's blog. 我是从某人的博客获得的。 It must sort big files. 它必须对大文件进行排序。 I preform it in separated thread: 我在单独的线程中执行它:

    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...";

}

For small files everything is normally, but for big files(about 4 gb), progressBar stops on some value for some reason during the splitting step. 对于小文件,一切正常,但对于大文件(大约4 gb),在拆分步骤中,由于某种原因,progressBar会停止某些值。 But splitting was finished. 但是拆分完成了。 What is reason of this stranges? 这种奇怪的原因是什么? PS I'm writing it on Mono and Gtk#. PS我正在Mono和Gtk#上编写它。

Like winforms, Gtk has thread affinity. 像winforms一样,Gtk具有线程相似性。 Your updates should happen on the main UI loop. 您的更新应在主UI循环上进行。 You can do this via: 您可以通过以下方式进行操作:

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

See also the mono Best Practices notes on this. 另请参见有关单声道最佳实践的说明。

You can't touch GUI objects from non-GUI thread. 您无法通过非GUI线程触摸GUI对象。 Results are unpredictable. 结果是不可预测的。 Sometimes it will throw an exception, but not always. 有时它将引发异常,但并非总是如此。

Instead, use the Invoke or BeginInvoke method (former is better). 而是使用InvokeBeginInvoke方法(以前更好)。 Like so: 像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM