Control.Invoke 与使用 TaskScheduler 的任务

发布于 2024-11-04 01:04:21 字数 398 浏览 0 评论 0原文

我查遍了一切,但找不到答案。 使用:

{
...
RefreshPaintDelegate PaintDelegate = new RefreshPaintDelegate(RefreshPaint);
Control.Invoke(PaintDelegate);
}

protected void RefreshPaint()
{
    this.Refresh();
}

...或...是更好、更差还是无关紧要?

Task.Factory.StartNew(() =>
{
    this.Refresh();
},
CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);

I've looked all over and I can't find an answer.
Is it better, worse, or indifferent to use:

{
...
RefreshPaintDelegate PaintDelegate = new RefreshPaintDelegate(RefreshPaint);
Control.Invoke(PaintDelegate);
}

protected void RefreshPaint()
{
    this.Refresh();
}

...or...

Task.Factory.StartNew(() =>
{
    this.Refresh();
},
CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

郁金香雨 2024-11-11 01:04:21

假设 uiScheduler 是一个调度程序,它将调用委托给 UI 线程,我想说,从功能上来说,使用两者是无关紧要的(例外的是对 Control.Invoke 的调用将阻塞,直到调用完成,而对 Task 的调用则不会,但是,您始终可以使用 Control.BeginInvoke 使它们在语义上等效)。

从语义的角度来看,我认为使用 Control.Invoke(PaintDelegate) 是一种更好的方法;当使用Task时,您正在隐式声明您想要执行一个工作单元,通常,该工作单元具有与其他工作单元一起调度的上下文,它是调度程序它决定如何委派该工作(通常是多线程的,但在本例中,它被编组到 UI 线程)。还应该说的是,uiSchedulerControl 之间没有明确的链接,而 Control 链接到应该进行调用的 UI 线程(通常,它们是都是一样的,但是可以有多个 UI 线程,尽管非常罕见)。

但是,在使用 Control.Invoke 时,您想要执行的操作的意图很明确,您希望将调用编组到 Control 正在向其发送消息的 UI 线程,这个调用完美地表明了这一点。

然而,我认为最好的选择是使用 SynchronizationContext 实例;它抽象出这样一个事实:您需要同步对该上下文的调用,而不是其他两个选项,这两个选项要么对调用中的意图不明确(Task),要么在方式上非常具体正在完成(Control.Invoke)。

Assuming that uiScheduler is a scheduler that will delegate the calls to the UI thread, I would say that functionally, using the two is indifferent (with the exception that the call to Control.Invoke will block until the call completes, whereas the call to Task will not, however, you can always use Control.BeginInvoke to make them semantically equivalent).

From a semantic point of view, I'd say that using Control.Invoke(PaintDelegate) is a much better approach; when using a Task you are making an implicit declaration that you want to perform a unit of work, and typically, that unit of work has the context of being scheduled along with other units of work, it's the scheduler that determines how that work is delegated (typically, it's multi-threaded, but in this case, it's marshaled to the UI thread). It should also be said that there is no clear link between the uiScheduler and the Control which is linked to the UI thread that the call should be made one (typically, they are all the same, but it's possible to have multiple UI threads, although very rare).

However, in using Control.Invoke, the intention of what you want to do is clear, you want to marshal the call to the UI thread that the Control is pumping messages on, and this call indicates that perfectly.

I think the best option, however, is to use a SynchronizationContext instance; it abstracts out the fact that you need to synchronize calls to that context, as opposed to the other two options, which are either ambiguous about the intent in the call (Task) or very specific in the way it is being done (Control.Invoke).

巷雨优美回忆 2024-11-11 01:04:21

它不一样。第一个版本将阻塞调用线程,直到 UI 线程准备好调用该方法。对于非阻塞版本,您应该使用 Control.BeginInvoke,它也会立即返回。

除此之外(如果将任务与线程池线程进行比较),使用它们几乎没有什么区别。

[编辑]

在这种情况下, Task.Factory.StartNewControl.BeginInvoke 之间没有区别(但不是我上面写的 Invoke ),因为只有一个 GUI 线程可以执行您的代码。无论您使用其中任何一个进行多少次调用,当 UI 线程空闲时,它们仍然会按顺序执行。

It is not same. First version will block the calling thread until UI thread is ready to invoke the method. For a non blocking version, you should use Control.BeginInvoke, which also returns immediately.

Apart from that (if you are comparing Task to a Thread Pool thread), there is little difference in using them.

[Edit]

In this case, there is no difference between Task.Factory.StartNew and Control.BeginInvoke (but not Invoke as I wrote above), since there is only a single GUI thread which can execute your code. No matter how many calls you make using either of them, they will still execute sequentially when UI thread becomes free.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文