Gra*_*ton 5 c# backgroundworker winforms
BackgroundWorker在c#中是否安全?
我问这个的原因是因为我得到了一个
在一个线程上创建的控件不能作为另一个线程上的控件的父级
它的例外.这是我的DoWork事件代码:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var openFile = document.Open(MyFileName);
e.Result = openFile;
}
Run Code Online (Sandbox Code Playgroud)
其中document是在创建父窗体时初始化的UI控件.在Open方法期间,document将填充各种属性.
我试图更改代码以调用,但同样的问题仍然存在.即
document.GetType().GetMethod("Open)".Invoke(document, new object[]{MyFileName})
Run Code Online (Sandbox Code Playgroud)
将产生与上述相同的错误.
知道如何操纵document控件吗?换句话说,如何使上面的代码工作?
编辑:有人建议我使用Control.Invoke,但它仍然无效(两个线程都被绞死).这是我试过的代码:
private delegate bool OpenFile(string filePath);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenFile oF = new OpenFile(document.Open);
var openFile = Invoke(oF, MyFileName); // it doesn't really matter whether I use BeginInvoke or Invoke, or other Control.Invoke, the end result is the same. Both the main thread hosting the document and the thread that launches the UI hanged.
e.Result = openFile;
}
Run Code Online (Sandbox Code Playgroud)
这不是线程的问题,而是它试图在UI控件上调用方法.在WPF和WinForms中,控件只能在UI线程上调用(通常有一个).你没有说你正在使用哪个,但你需要调用Control.InvokeWinForms或Dispatcher.InvokeWPF 的方法.
Invoke()您显示的反射方法实际上将在当前线程上调用该方法.
虽然我不清楚 a 的线程安全性到底是什么意思BackgroundWorker,但问题不在于该对象;而是在于该对象。Windows 窗体控件设计为在单个线程(UI 线程)上进行操作。您不应在不同线程上操作 Windows 窗体对象。您可以使用该Control.Invoke方法从其他线程调用UI线程中的操作(Invoke您当前使用的方法是通过反射提供的,与此问题完全无关):
Invoke(new Action(MethodToRunInUIThread));
void MethodToRunInUIThread() {
// do stuff here.
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您所做的只是操作 UI 对象,那么使用后台工作程序就没有意义。
| 归档时间: |
|
| 查看次数: |
1796 次 |
| 最近记录: |