开发者

Events from another thread in C#

开发者 https://www.devze.com 2023-02-14 22:11 出处:网络
I have a such code: http://pastie.org/1638879 I got it from someone\'s blog. It must sort big files. I preform it in separated thread:

I have a such code: 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. But splitting was finished. What is reason of this stranges? P.S. I'm writing it on Mono and Gtk#.


Like winforms, Gtk has thread affinity. Your updates should happen on the main UI loop. 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. Results are unpredictable. Sometimes it will throw an exception, but not always.

Instead, use the Invoke or BeginInvoke method (former is better). Like so:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号