C# 使用TaskScheduler调用vs任务

C# 使用TaskScheduler调用vs任务,c#,multithreading,task,C#,Multithreading,Task,我找遍了,找不到答案。 使用是更好、更差还是无关紧要: { ... RefreshPaintDelegate PaintDelegate = new RefreshPaintDelegate(RefreshPaint); Control.Invoke(PaintDelegate); } protected void RefreshPaint() { this.Refresh(); } ……或者 Task.Factory.StartNew(() => { this.Ref

我找遍了,找不到答案。 使用是更好、更差还是无关紧要:

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

protected void RefreshPaint()
{
    this.Refresh();
}
……或者

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

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

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

[编辑]


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

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

从语义的角度来看,我认为使用
Control.Invoke(PaintDelegate)
是一种更好的方法;当使用
任务时
会隐式声明要执行一个工作单元,通常,该工作单元与其他工作单元一起被安排,由调度器决定如何委派该工作(通常,它是多线程的,但在本例中,它被封送到UI线程)。还应该说,
uiScheduler
和链接到UI线程的
控件
之间没有明确的链接,该调用应该在其中进行(通常,它们都是相同的,但是可以有多个UI线程,尽管非常罕见)

但是,在使用
Control.Invoke
时,您想要做的事情的意图是明确的,您想要封送对
控件
正在泵送消息的UI线程的调用,此调用完美地表明了这一点

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

但不会。语法与
Invoke
相同,但它是异步的。有关详细信息,请查看。因此Task.Factory.StartNew()将对并行性更开放?它将安排刷新并允许调用线程继续,对吗?