这是异步调用同步方法的正确方法吗?
我使用的是这样的代码:
handler.Invoke(sender, e);
但该代码的问题是它是同步的,它真正做的只是更新 GUI。服务器没有必要等待它完成,因此应该将其设置为异步。
我真的不想使用 BeginInvoke 和 EndInvoke,因为在这种情况下不需要回调方法。
这是一个合适的替代方案吗?
Task.Factory.StartNew(() => handler.Invoke(sender, e));
I was using code like this:
handler.Invoke(sender, e);
But the problem with that code is that it is synchronous and all it really does is update the GUI. It is not necessary for the server to wait for it to complete so it should be made asynchronous.
I don't really want to use BeginInvoke and EndInvoke because a callback method is not necessary in this case.
Is this a suitable alternative?
Task.Factory.StartNew(() => handler.Invoke(sender, e));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您这样做的方式很好,在 .NET 3.5 上执行此操作的另一种方法是使用 ThreadPool 类。
另外,如果处理程序恰好是从控件派生的,则 您可以在没有相应 EndInvoke 的情况下调用 BeginInvoke。
The way you did it is fine, another way to do this that works on .NET 3.5 is using the
ThreadPool
class insteadAlso if handler happens to be a derived from control, you are allowed to call BeginInvoke without a corresponding EndInvoke.
对 GUI 的调用很特殊,因为它们必须始终从 GUI 线程完成。用你自己的话说,handler.Invoke(sender, e)“更新了 GUI”,但它(可能)不是从 GUI 线程执行的,所以它当前的形式并不好。
在 WinForms 中,您需要将任务委托包装到
Control.Invoke
中(或者忘记任务,只使用Control.BeginInvoke
)。如果是 WPF,您可以将任务委托包装到 Dispatcher.Invoke 中(或者仅使用没有任务的 Dispatcher.BeginInvoke)。
Calls to GUI are special in that they must always be done from the GUI thread. In your own words,
handler.Invoke(sender, e)
"updates the GUI", yet it is (probably) not executed from the GUI thread, so it not OK in its current form.In WinForms, you'll need to wrap your task delegate into
Control.Invoke
(or forget about tasks and just useControl.BeginInvoke
).If WPF, you can wrap your task delegate into
Dispatcher.Invoke
(or just useDispatcher.BeginInvoke
without a task).我不熟悉 C# 4 的 Task 类,但我知道 BeginInvoke 在没有 EndInvoke 的情况下也能正常工作。我有时会写这样的代码:
编辑:我错了。虽然 EndInvoke 并不是使代码在新线程上执行所必需的,但文档明确指出 EndInvoke 很重要。
I'm not familiar with C# 4's Task class, but I know BeginInvoke works just fine without EndInvoke. I sometimes write code like this:
Edit: I was mistaken. While EndInvoke is not necessary to cause the code to execute on a new thread, the documentation clearly states that EndInvoke is important.