【发布时间】:2011-09-10 08:40:29
【问题描述】:
我注意到 control.BeginInvoke(delegate) 有时无法调用委托。我知道 BeginInvoke 只是创建一个 PostMessage 并且该消息稍后由应用程序处理(默认情况下发布消息限制为 10,000)。鉴于我们的应用程序不是很复杂,是否还有其他原因导致它无法执行委托?我的代码如下所示。
class MyClass : Form{
private bool executing = false;
private delegate void DelegateBar(string info, int total, bool status, object obj);
private void Bar(string info, int total, bool status, object obj){
log("Enterning Bar");
// Update something on UI
executing = false;
log("Exiting Bar");
}
public void foo(){
log("Entering Foo");
executing = true;
try{
// do something over the network
}catch(Exception e){
// probably network down. Lets not worry about it
}
DelegateBar barPtr = new DelegateBar(Bar);
// Update UI .. call on form : form is a control
this.BeginInvoke(barPtr, new object[] {"someInfo", 3, false, null});
log("Exiting Fool");
}
public void callMeEveryFiveSeconds(){
if(!executing) foo();
}
private delegate void DelegateCallMe();
// execute every 5 seconds.
private void timer1_Tick(object sender, EventArgs e)
{
Delegate del = new DelegateCallMe(callMeEveryFiveSeconds);
// appoligies if syntax is not right, it to convey the idea that callMeEveryFiveSeconds is called on the main thread (asynchronously)
this.beginInvoke(del, new object[]{});
}
}
【问题讨论】:
-
为什么 Bar 的签名和 DelagetBar 的签名不一样?这些应该匹配
-
哦..这是一个错字。我已经编辑了帖子。
-
您确定在调用 BeginInvoke 之前表单已完全加载? social.msdn.microsoft.com/forums/en-US/winforms/thread/…
-
@Christian,是的,表单已加载。我们的一位用户抱怨应用程序挂起。查看日志,我们发现 Bar 在过去 7-8 小时内每 5 秒被调用一次,并且在用户报告其挂起之前正常工作。
-
你的 executing 标志没有做你希望的事情。您使用的测试和设置操作是基本的线程竞赛。您必须使用 lock 语句来防止两个线程同时进入 foo()。五秒钟的延迟将使它在大部分时间都可以工作。直到机器负载很重。
标签: c# delegates begininvoke