我有这样的代码:http://pastie.org/1638879
我是从某人的博客上得到的。它必须排序大文件。 我在分开的线程中预先形成它:
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#上写的。
答案 0 :(得分:3)
与winforms一样,Gtk具有线程亲和力。您的更新应在主UI循环上进行。您可以通过以下方式执行此操作:
protected virtual void fileSortProgressMerging(FileSort o, double progress) {
Gtk.Application.Invoke (delegate {
progressBar.Fraction = progress;
progressBar.Text = "Merging...";
});
}
另请参阅mono Best Practices关于此的说明。
答案 1 :(得分:2)
您无法从非GUI线程触摸GUI对象。结果是不可预测的。有时它会引发异常,但并非总是如此。
相反,请使用Invoke
或BeginInvoke
方法(以前更好)。像这样:
protected virtual void fileSortProgressSplitting(FileSort o, double progress)
{
BeginInvoke( new Action( () =>
{
progressBar.Fraction = progress;
progressBar.Text = "Splitting...";
} );
}