在UI线程中加载大型文档时,即使已实施BackgroundWorker,UI也无响应

时间:2010-01-19 02:48:43

标签: c# winforms backgroundworker

我问similar question here;感谢所有提出建议的人!但是,似乎我的问题比上面描述的要大,所以我发布了一个新问题。

问题是,当我使用名为document的第三方控件加载大型文档时,我需要保持我的UI响应。 document是嵌入在第三方控件中的类,我没有办法新建它,并且它没有Invoke函数。

我正在尝试使用Backgroundworker。我尝试的代码是这种形式:

public class MyForm: Form
{
private delegate bool OpenFile(string filePath);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{



    OpenFile oF = new OpenFile(document.Open);
    var openFile = this.Invoke(oF, MyFileName);  

    e.Result = openFile;
}
}

现在,在document所属的UI线程中,当它执行Open操作时,应该出现一个对话框并自行更新,主线程应该保持响应(也就是说,无论如何,我仍然可以拖放表格)。这就是我想要实现的目标。

问题是上面的代码会使我的两个线程(主UI线程和对话框线程)在加载期间挂起。 我的问题是,无论如何都要解决这个问题吗?

P / S:我尝过var openFile = Invoke(oF, MyFileName)var openFile = BeginInvoke(oF, MyFileName)以及var openFile = OtherControl.Invoke(oF, MyFileName),但都没有帮助。

2 个答案:

答案 0 :(得分:2)

您所包含的示例显示不足以清楚地识别问题。我的假设是您的类不包含明确的Invoke()方法,因此您的示例是调用Form.Invoke()。如果是这种情况,那么你就误解了那种方法的目的。

Form.Invoke()确保包含的委托在UI线程上执行。因此,您的后台线程实际上并没有完成工作,而是您的后台线程在执行委托之前返回到您的UI线程...因此无响应的UI。

你可能是一个不幸的歧义的受害者...... System.DelegateSystem.Windows.Forms.Form& Control包含名为Invoke()BeginInvoke()的方法,但用途不同。不幸的是,这是您的样本有点不完整的地方。 OpenFile是代表吗?您的班级是否包含明确的Invoke()方法?


更新:在评论中进行了一些讨论后,可行的选项被削减为:

  • 尝试将数据预加载到后台线程上的临时内存位置,然后从该位置加载第三方UI控件,而不是从文件系统/网络加载

  • 使用.NET Reflector检查控件的内部/非公共API,并尝试使用Reflection通过调用非公共方法或设置字段/属性来覆盖当前行为

答案 1 :(得分:0)

较早的问题,但没有答案标记为正确,所以我认为问题没有得到当前答案的解决。

我遇到了同样症状的问题。使用后台工作者线程,UI bacame无响应。

我基本上遵循了以下教程: http://msdn.microsoft.com/en-us/library/hybbz6ke.aspx http://broadcast.oreilly.com/2010/06/understanding-c-using-backgrou.html

报告了一些进展并陷入了无响应的用户界面。事实证明,我为快速进步付出了很多努力,只是更新了我的UI响应的进度。将每个thousend项目的进度更新数量更改为一个解决了我的问题。

希望这有帮助。