我问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)
,但都没有帮助。
答案 0 :(得分:2)
您所包含的示例显示不足以清楚地识别问题。我的假设是您的类不包含明确的Invoke()
方法,因此您的示例是调用Form.Invoke()
。如果是这种情况,那么你就误解了那种方法的目的。
Form.Invoke()
确保包含的委托在UI线程上执行。因此,您的后台线程实际上并没有完成工作,而是您的后台线程在执行委托之前返回到您的UI线程...因此无响应的UI。
你可能是一个不幸的歧义的受害者...... System.Delegate
和System.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项目的进度更新数量更改为一个解决了我的问题。
希望这有帮助。