什么是错与我的交叉线呼吁在Windows形式?
-
27-09-2019 - |
题
我遇到一个问题与Windows形式应用程序。
形式必须显示从另外一个线程。因此,在形成类,我有下列代码:
private delegate void DisplayDialogCallback();
public void DisplayDialog()
{
if (this.InvokeRequired)
{
this.Invoke(new DisplayDialogCallback(DisplayDialog));
}
else
{
this.ShowDialog();
}
}
现在,每次我经营这个, InvalidOperationException
是扔在线 this.ShowDialog();
:
"跨线操作无效:控制'SampleForm'访问时从一个线程比其他的线创建它。"
什么是错的这段代码?是不是一个有效方法,使跨线的电话?是不是有什么特别的 ShowDialog()
?
解决方案
试试这个:
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
}
}
}
请注意, InvokeRequired
返回
真的,如果控制的处理是 上创建一个不同的线比 叫线(指示您 必须打电话来控制通过 调用的方法);否则,假。
因此,如果控制尚未建立,返回值将 false
!
其他提示
你可能执行这些代码前的形式已经显示。
因此, InvokeRequired
正在返回 false
.
我相信这里发生了什么的是,这个代码是正在运行之前 Form
是有史以来所示。
当一个 Form
创建中。净它不会立即获得亲和对于特定的线。只有当某些行动的执行等,表示它或夺取的处理不得力。在此之前发生的很难 InvokeRequired
能够正常工作。
在这种特定情况下没有亲和力的建立和没有父母控制存在这样 InvokeRequired
返回虚假的因为它不能确定原始的线。
的方式来解决这个问题是建立亲对你的控制时,它的创建UI上的螺纹。最好的方式做到这仅仅是要求控制对于它处理的财产。
var notUsed = control.Handle;
你可能会获得这个代码前的形式已经显示出,因此窗口处理尚未建立。
你可以添加这段代码之前你代码和所有的应该是好的:
if (! this.IsHandleCreated)
this.CreateHandle();
编辑: 还有另外一个问题与你的代码。一旦形式显示,你无法叫ShowDialog()。你会得到一个无效运行异常。你可能希望修改这种方法为其他人已经提出了建议。
你可能会得到更好的服务,叫ShowDialog()直接从呼叫类,并有另一个方法BringToFront()或类似的东西...
你总是可以尝试试对一个不同的控制。
例如,你可以进入应用程序。形式收藏
public Control GetControlToInvokeAgainst()
{
if(Application.Forms.Count > 0)
{
return Application.Forms[0];
}
return null;
}
然后在你DisplayDialog()方法,调GetControlToInvokeAgainst()并测试空前努力来执行一个invokerequired的呼吁。
最有可能处理的控制并不是创建然而,在这种情况下 Control.InvokeRequired
返回 false
.
检查 Control.IsHandleCreated
酒店看到的,如果是这种情况。
我还认为SLaks是正确的。从msdn(http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx):
如果没有适当处理,可以发现,InvokeRequired方法返回错误的。
如果它能够在你的种情况下,我将试图结合建立,并表示控制在一个单一的方法,即:
public DisplayDialog static Show()
{
var result = new DisplayDialog; //possibly cache instance of the dialog if needed, but this could be tricky
result.ShowDialog();
return result;
}
你可以打电话显示从一个不同的纹