Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#在UI线程中等待_C# - Fatal编程技术网

C#在UI线程中等待

C#在UI线程中等待,c#,C#,根据Microsoft Visual C#循序渐进第9版: wait运算符指示方法应由单独的任务运行, 并且调用代码被挂起,直到方法调用完成。 调用代码使用的线程被释放并重用。 如果线程是用户界面线程,这一点很重要,因为它使用户界面保持响应 假设我有一个绑定IO并释放CPU的方法: private async Task DoLongRunningIO() { ... } 以上段落是否意味着跑步 await DoLongRunningIO(); message.Text = "

根据Microsoft Visual C#循序渐进第9版:

wait运算符指示方法应由单独的任务运行, 并且调用代码被挂起,直到方法调用完成。 调用代码使用的线程被释放并重用。 如果线程是用户界面线程,这一点很重要,因为它使用户界面保持响应

假设我有一个绑定IO并释放CPU的方法:

private async Task DoLongRunningIO()
{
    ...
}
以上段落是否意味着跑步

await DoLongRunningIO();
message.Text = "Done";
在UI线程释放后,UI线程是否仍将保持UI响应?(与会阻塞UI线程的
DoLongRunningIO().Wait()
相反)

如果答案是肯定的,我假设如果长时间运行的任务是CPU密集型的,那么它就不是真的,因为在这种情况下UI线程仍然被消耗

以上段落是否意味着跑步

await DoLongRunningIO();
message.Text = "Done";
等待DoLongRunningIO();
message.Text=“完成”;
在UI线程释放后,UI线程是否仍将保持UI响应

如果答案是肯定的,我假设如果长时间运行的任务是CPU密集型的,那么它就不是真的,因为在这种情况下UI线程仍然被消耗

不,你的假设是错误的。“线程”和“CPU”不是一回事。即使您的机器只有一个CPU,也可能有一个CPU密集型线程在运行,UI线程在运行,操作系统将在它们之间共享CPU。您可能会发现响应能力略有下降,但UI线程仍然能够运行

如果您有多个CPU核心,就像几乎所有现代硬件一样,那么只要这两个线程不交互,UI线程就能够畅通无阻地运行,即使还有一个CPU密集型线程在运行

请注意,这一切都假定
DoLongRunningIO()
方法编写正确,即实际上反映了异步处理的操作。对于CPU密集型任务,这通常包括调用
task.Run()
来执行操作,当然也可以使用其他机制

如果该方法写得不正确,则所有赌注都将被取消。您没有提供有关该方法的任何详细信息,因此无法确定您的场景中是否存在这种情况


旁白:


值得一提的是,我反对您从书中引用的“等待操作符表示一个方法应该由单独的任务运行”这句话。
await
操作符没有说明应该如何运行/调用/执行方法或操作等。
await
所做的唯一一件事是指出当前方法中的一个点,即给定一个等待的对象(通常是一个
任务
),如果对象未处于完成状态,则该方法应返回调用方。这取决于生成等待对象的任何表达式如何处理任务的创建,以及任务是在单独的线程中完成还是以异步方式完成。

这听起来不像是这里的问题。这听起来像是你可以很容易地为自己设置测试和发现的东西。@Enigmativity我不同意-这不容易测试。@EJoshuaS-为什么不呢?因为我的理解是等待在调用线程中安排任务。如果调用线程是UI,则根据此逻辑,当我实际想要测试其响应性时,它将挂起UI线程。我的理解正在辩论中。我很可能不得不设置一个测试来找出我自己。@youn-你似乎对
await
有一个错误的印象,我认为这是这本书的错。我认为await关键字专门将任务安排在调用方法的线程上(即,它不会产生新线程)。因此,我对正在使用的UI线程发表了评论。书中的同一章:当C#编译器在异步方法中遇到wait运算符时,它会将跟随该运算符的操作数有效地重新格式化为与异步方法在同一线程上运行的任务。“我认为wait关键字专门在调用方法的线程上调度任务”——否,这是对
wait
运算符的完全错误理解。见我的编辑上面;
wait
操作员与安排等待的工作无关。它只控制当前方法处理等待等待工作的机制(特别是通过设置编译器生成的状态机,使方法可以在适当的位置恢复,然后返回给调用方)。我真的不喜欢你引用的书。如果它真的说“它有效地将遵循此运算符的操作数重新格式化为与异步方法在同一线程上运行的任务”,那么它就不是一本应该使用的书。
await
运算符不会“重新格式化”任何内容,当然也不会影响运算符的操作数(即等待表达式)的执行位置。它会影响包含
await
语句的方法中的代码的执行位置,例如,允许该方法返回到原始线程,如在UI线程中。“你是说C#可以在另一个线程上安排等待的任务吗?”--我是说等待一项任务与该任务的日程安排无关。当代码开始等待时,调度已经完成。就调度而言,等待是完全不相关的。等待与任务调度无关。如何安排它取决于任务本身。wait仅指定任务完成后如何恢复此功能。