Ars*_*nko 9 c# multithreading invoke showdialog winforms
我遇到Windows窗体应用程序的问题.
必须从另一个线程显示表单.所以在表单类中,我有以下代码:
private delegate void DisplayDialogCallback();
public void DisplayDialog()
{
if (this.InvokeRequired)
{
this.Invoke(new DisplayDialogCallback(DisplayDialog));
}
else
{
this.ShowDialog();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,每次我运行它时,InvalidOperationException都会抛出一条线this.ShowDialog();:
"跨线程操作无效:控制'SampleForm'从其创建的线程以外的线程访问."
这段代码有什么问题?这不是一种进行跨线程调用的有效方法吗?有什么特别的ShowDialog()吗?
我相信这里发生的事情是这个代码在Form显示之前就已经运行了.
当Form在.Net中创建a时,它不会立即获得对特定线程的亲和力.只有在执行某些操作时,如显示它或抓住手柄才能获得亲和力.在此之前,很难InvokeRequired正常运作.
在这种特殊情况下,没有建立亲和关系并且不存在父控件,因此 InvokeRequired返回false,因为它无法确定原始线程.
解决此问题的方法是在UI线程上创建控件时建立关联.执行此操作的最佳方法是向控件询问其handle属性.
var notUsed = control.Handle;
Run Code Online (Sandbox Code Playgroud)
试试这个:
private delegate void DisplayDialogCallback();
public void DisplayDialog()
{
if (this.InvokeRequired)
{
this.Invoke(new DisplayDialogCallback(DisplayDialog));
}
else
{
if (this.Handle != (IntPtr)0) // you can also use: this.IsHandleCreated
{
this.ShowDialog();
if (this.CanFocus)
{
this.Focus();
}
}
else
{
// Handle the error
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,InvokeRequired返回
如果控件的 Handle 是在与调用线程不同的线程上创建的,则为 true(表示您必须通过 invoke 方法调用控件);否则为假。
因此,如果尚未创建控件,则返回值将为false!
| 归档时间: |
|
| 查看次数: |
7826 次 |
| 最近记录: |