在Disposed控件上调用InvokeRequired / BeginInvoke()? [英] InvokeRequired/BeginInvoke() on Disposed control?

查看:93
本文介绍了在Disposed控件上调用InvokeRequired / BeginInvoke()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一个显示数据的表单(对你来说是否足够模糊?)。

数据来自线程池线程。由于线程池线程不是与UI线程相同的
,我的表单的回调函数遵循

标准设计模式:


if(IsDisposed){

return;

}

if(InvokeRequired){

this .BeginInvoke(delegateToThisMethod,new Object [] {args ...});

返回;

}

....绘画代码这里......


这里的想法是:如果用户关闭了表格(已经处理完毕),那么

只是忽略了传入的数据。如果表单仍然打开,请通过

显示一些绘制代码,但是在表单的UI线程上执行此操作。没什么太不寻常的

这里。我的问题是:如果在已经处理了
的表单上调用BeginInvoke()会发生什么?这种情况可能发生在以下情况:


在上面的代码中,让我们说this.BeingInvoke()调用只是

即将到来执行,但然后发生上下文切换并且用户的请求

关闭窗口,这导致窗体上的Dispose()调用。

上下文然后切换回我的BeginInvoke()调用,然后根据已处理的表格进行
。这是一个问题吗?从我的角度来看,我不需要关心,因为我的代码顶部的IsDisposed检查应该抓住这个......但是内部会有WinForms吗?有一个问题是

BeginInvoke()是在窗口句柄已被处理的窗体上调用的吗?


-

此致,


David Sworder
http://www.codeFanatic.com

推荐答案

David,

我不相信这会是一个问题。基本上,在调用

Invoke / BeginInvoke时,会向窗口发送一条消息(使用窗口句柄)。

现在,那个窗口可以是你的窗体''窗口,或者它可以是另一个窗口。这个

取决于调用Invoke的控件。如果表格是

处理,那么将使用另一个窗口。


虽然你可以在BeginInvoke之前查看电话,看看表格是否

被处置,你也应该调用传递给

BeginInvoke的方法,当你在线程上调用Invoke不是

要求。如果你被安置在那里,那么你不应该打电话给你的代码,然后退出。


希望这会有所帮助。

-

- Nicholas Paldino [.NET / C#MVP]

- mv*@spam.guard.caspershouse.com


" David Sworder" < DS ****** @ cts.com>在留言中写道

news:u%****************** @ TK2MSFTNGP12.phx.gbl ...
David,

I don''t believe this will be a problem. Basically, during a call to
Invoke/BeginInvoke, a message is sent to a window (using a window handle).
Now, that window can be your form''s window, or it can be another one. This
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.

While you could check on the call before BeginInvoke to see if the form
is disposed, you should also call in the method that is passed to
BeginInvoke as well, when you are on the thread that an Invoke is not
required on. If you are disposed there, then you should not call the rest
of your code, and then exit.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"David Sworder" <ds******@cts.com> wrote in message
news:u%******************@TK2MSFTNGP12.phx.gbl...


我有一个显示数据的表单(对你来说是否足够模糊?)。
数据来自线程池线程。由于线程池线程与UI线程不同,我的表单的回调函数遵循
标准设计模式:

if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object [] {args ...});
return;
}
...在这里绘画代码.....

这里的想法是:如果用户关闭了表单(它被处理掉了),那么
然后就会忽略传入的数据。如果表单仍然打开,请通过一些绘图代码显示数据
,但是在表单的UI线程上执行此操作。没什么太不寻常的
在这里。我的问题是:如果在已经处理的表单
上调用BeginInvoke()会发生什么?这可能发生在以下情况:

在上面的代码中,让我们说this.BeingInvoke()调用即将执行,但然后发生上下文切换并且用户请求关闭窗口,这导致
表单上的Dispose()调用。然后上下文切换回我的BeginInvoke()调用,然后对着已处理的表单进行
。这是一个问题吗?从我的角度来看,我不在乎,因为我的代码顶部的'IsDisposed'检查应该抓住这个......但是WinForms内部会有一个问题,就是
正在窗口句柄被处理的窗体上调用BeginInvoke()?

真诚的,

David Sworder
http://www.CodeFanatic.com






" David Sworder" < DS ****** @ cts.com>在留言中写道

news:u%****************** @ TK2MSFTNGP12.phx.gbl ...
Hi,

"David Sworder" <ds******@cts.com> wrote in message
news:u%******************@TK2MSFTNGP12.phx.gbl...


我有一个显示数据的表单(对你来说是否足够模糊?)。
数据来自线程池线程。由于线程池线程与UI线程不同,我的表单的回调函数遵循
标准设计模式:

if(IsDisposed){
return;
}
if(InvokeRequired){
this.BeginInvoke(delegateToThisMethod,new Object [] {args ...});
return;
}
...在这里绘画代码.....

这里的想法是:如果用户关闭了表单(它被处理掉了),那么
然后就会忽略传入的数据。如果表单仍然打开,请通过一些绘图代码显示数据
,但是在表单的UI线程上执行此操作。没什么太不寻常的
在这里。我的问题是:如果在已经处理的表单
上调用BeginInvoke()会发生什么?在以下情况下可能会发生这种情况:


您将获得一个运行时异常,声明在

已经处置的对象上调用了Invoke。


顺便说一句,我会在OnPaint中进行绘画,如果

数据到达,则调用Ivalidate(你的回调信号)。 Invalidate触发

绘画。

在上面的代码中,让我们说this.BeingInvoke()调用即将执行,但是然后发生一个上下文切换,用户的请求关闭窗口,这导致
表格上的Dispose()调用。然后上下文切换回我的BeginInvoke()调用,然后对着已处理的表单进行
。这是一个问题吗?从我的角度来看,我是
[...] -
David Sworder
http://www.codeFanatic.com




这可能会导致问题。我在类似的设置中遇到了这个问题。

我通过保留一个标志来表明表单是否正在关闭来解决它。

将标志初始化为false。锁定关闭标志的对象。在

OnClosing处理程序中,从这开始:


lock(closingLock)

{

isClosing = true;

}

// ...其他结束代码


在回调方法中,执行保护的所有内容closingLock(

只不过是一个互斥锁)。


锁定(closingLock)

{

if(!isClosing)

this.BeginInvoke(delegateToThisMethod,new Object [] {args ...});

}

如果您遵循我的建议,则调用Invalidate而不是您的绘画

处理程序,并根据可用数据绘制OnPaint处理程序。


干杯,

---

Tom Tempelaere



This could lead to problems. I had this problem myself in a similar setting.
I solved it by keeping a flag to indicate whether the form is closing.
Initialize the flag to false.Make a lock object for the closing flag. In the
OnClosing handler, begin with this:

lock( closingLock )
{
isClosing = true;
}
// ... other closing code

In the callback method, execute everything guarded by the closingLock (which
is nothing more than a mutex).

lock( closingLock )
{
if( ! isClosing )
this.BeginInvoke(delegateToThisMethod, new Object[]{args...});
}

If you follow my advice, you invoke Invalidate instead of your painting
handler, and have the OnPaint handler paint based on the available data.

Cheers,
---
Tom Tempelaere


>现在,该窗口可以是窗体的窗口,也可以是另一个窗口。

这个
> Now, that window can be your form''s window, or it can be another one.
This
依赖于调用Invoke的控件。如果表格被处理掉,那么将使用另一个窗口。
is dependent on the control that Invoke is called on. If the form is
disposed, then another window will be used.




另一个窗口?哪一个?


David



Another window? Which one?

David


这篇关于在Disposed控件上调用InvokeRequired / BeginInvoke()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆