2011-10-01 183 views
3

我用这样的代码:这是异步调用同步方法的正确方法吗?

handler.Invoke(sender, e); 

但随着代码的问题是,它是同步的,它确实做到的就是更新GUI。服务器不需要等待它完成,因此它应该是异步的。

我真的不想使用BeginInvoke和EndInvoke,因为在这种情况下不需要回调方法。

这是一个合适的选择吗?

Task.Factory.StartNew(() => handler.Invoke(sender, e)); 
+0

'handler'是什么类型? – svick

+0

@svick:'EventHandler ' –

+0

您所想的一切实际上并不奏效。如果你想在UI线程上运行代码,然后使用Dispatcher.Invoke或Control.BeginInvoke(),无论你选择的是哪个库。 –

回答

-1

我不熟悉C#4的Task类,但我知道BeginInvoke在没有EndInvoke的情况下工作得很好。我有时会这样写代码:

handler.BeginInvoke(sender, e, null, null); 

编辑:我错了。尽管EndInvoke并不是使代码在新线程上执行所必需的,但文档清楚地指出EndInvoke非常重要。

+2

有了这段代码,'handler'抛出的任何异常都会被忽略。所以如果你想这样做,你最好知道你在做什么。 – svick

+0

@Joshua:是的,但是如文档所述,BeginInvoke调用必须以EndInvoke调用(通常放在回调中)结束。 –

+0

@svick:好点。但是,Task.Factory.StartNew必须具有相同的问题,因为异常只能在引发它们的线程中捕获。你必须知道你在做什么。 –

0

对GUI的调用很特别,因为它们必须始终从GUI线程完成。用你自己的话说,handler.Invoke(sender, e)“更新GUI”,但它可能(不可能)从GUI线程执行,所以它在当前形式中不能正确执行。

在WinForms中,您需要将您的任务代理包装到Control.Invoke(或忘记任务并仅使用Control.BeginInvoke)。

如果是WPF,你可以将你的任务委托包装成Dispatcher.Invoke(或者只是在没有任务的情况下使用Dispatcher.BeginInvoke)。

+0

我已经在事件处理程序中这样做了。我想知道如果我也应该异步调用事件处理程序,如果是这样,如果最初发布的代码是正确的方式这样做。 –

相关问题