异步调用 - 需要EndInvoke吗?

7
可能重复:
必须每次调用BeginInvoke都跟着一个EndInvoke吗?
EndInvoke()是可选的、有点可选的还是一定不可选的? 我有一个多线程应用程序,其中一个辅助线程需要在每隔几分钟执行一次一些代码并在主线程上执行。没有返回值,并且第二个线程不关心是否引发任何异常或无法运行。
到目前为止,我一直通过Form.Invoke来运行代码,但有时需要比平常花费更长时间(几秒钟),并阻塞该线程直到完成。我需要第二个线程能够继续执行而不会停顿几秒钟。 BeginInvoke听起来很适合这项工作,但我真的没有任何地方可以调用EndInvoke,因为我不想等待它或获取返回值。考虑到被调用的代码涉及大量本地调用,我不确定不使用EndInvoke是否是一个好主意。
我是否需要调用EndInvoke,或者是否有其他异步在主窗体线程上运行代码的方法,我应该使用它来代替?
谢谢 =)
3个回答

7

太棒了,所以我只需要将我的Invoke改为BeginInvoke,而不会出现任何问题。 - William Lawn Stewart

5

通常调用EndInvoke的方法是在BeginInvoke中包含一个完成回调,以便您可以在回调中调用EndInvoke。这对于做比Invoke更具体的Begin/End方法(如BeginRead/EndRead)更为重要;在后一种情况下,End可能需要进行清理,并且通常(重新)抛出在过程中发生的任何异常。


3
你应该确保调用EndInvoke,但这很容易实现,可以像这样做:
  var action = new Action(SomeMethodGroup); 

  action.BeginInvoke(new AsyncCallback(

        x => (x.AsyncState as Action).EndInvoke(x)), action); 

我认为OP特指Form.BeginInvoke而非一般的Begin/EndInvoke模式。从MSDN来看,Form.BeginInvoke似乎并没有完全遵循Begin/EndInvoke模式。 - dtb
@dtb,实际上,我不认为对于Form.BeginInvoke或Delegate.BeginInvoke来说这是严格必要的,因为我相信它只有在您尝试等待(即调用EndInvoke)时才会创建WaitHandle。 WaitHandle需要被清理,但如果您已经调用了EndInvoke,它将被清理。 - Dan Bryant
好主意,也许你不需要EndInvoke,也许一个简单的方法作为“fire and forget”策略可能会起作用? - Sean Thoman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接