[英]Is the order of resume multiple await expressions to the same task is guaranteed?
I'm learning about async/await with C# 4.5 and wondering what happens when multiple "awaiters" are awaiting the same task. 我正在学习使用C#4.5进行异步/等待,并想知道当多个“等待者”正在等待同一任务时会发生什么。
I'm doing some experimentation and I think that I understand what's happening. 我正在做一些实验,我想我了解发生了什么。 However, i have some questions to ask: 但是,我有一些问题要问:
Look at this piece of code: 看一下这段代码:
AsyncAwaitExperiment.fxml.cs AsyncAwaitExperiment.fxml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace View
{
/// <summary>
/// Interaction logic for AsyncAwaitExperiment.xaml
/// </summary>
public partial class AsyncAwaitExperiment : Window
{
private CancellationTokenSource token;
private Task longRunningTask;
public AsyncAwaitExperiment()
{
InitializeComponent();
}
private void startAsyncOperation(object sender, RoutedEventArgs e)
{
if (longRunningTask != null && !longRunningTask.IsCompleted)
{
return;
}
else
{
longRunningTask = null;
token = new CancellationTokenSource();
}
Action action = () =>
{
while (!token.Token.IsCancellationRequested)
{
Thread.Sleep(100);
}
};
longRunningTask = Task.Factory.StartNew(
action,
token.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Current);
}
private void stopOperation(object sender, RoutedEventArgs e)
{
if (longRunningTask == null
|| longRunningTask.IsCompleted
|| token == null
|| token.Token.IsCancellationRequested)
{
return;
}
token.Cancel();
}
private async void firstAwait(object sender, RoutedEventArgs e)
{
if (longRunningTask == null || longRunningTask.IsCompleted)
return;
await longRunningTask;
Console.WriteLine("First Method");
}
private async void secondAwait(object sender, RoutedEventArgs e)
{
if (longRunningTask == null || longRunningTask.IsCompleted)
return;
await longRunningTask;
Console.WriteLine("Second Method");
}
}
}
AsyncAwaitExperiment.fxml AsyncAwaitExperiment.fxml
<Window x:Class="View.AsyncAwaitExperiment"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AsyncAwaitExperiment" Height="300" Width="300">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Start Async" Margin="3" Click="startAsyncOperation" />
<Button Content="Stop Async" Margin="3" Click="stopOperation" />
<Button Content="Await First" Margin="3" Click="firstAwait" />
<Button Content="Await Second" Margin="3" Click="secondAwait" />
</StackPanel>
</Grid>
</Window>
The behavior of this code is: 此代码的行为是:
With this piece of code and some break points I have noticed some behaviors. 通过这段代码和一些断点,我注意到了一些行为。
The questions are: 问题是:
PS: Sorry for my bad english :/ PS:对不起,我的英语不好:/
You shouldn't assume anything about the order in which activities will resume. 您不应对活动的恢复顺序承担任何责任。 Supposing that, in the future, someone managed to write a new UI system that was entirely multi-threaded, you'd expect even UI threads to run in parallel (Notes: No-one thinks it's sane to write a multi-threaded UI system currently; Even if two tasks resume "at the same time", one of them could be indefinitely paused) 假设将来有人设法编写一个完全是多线程的新UI系统,那么您甚至期望UI线程可以并行运行(注意:没有人认为编写多线程UI系统是理智的。当前;即使“同时”恢复执行两个任务,也可能会无限期地暂停其中一项)
If there are dependencies between activities in your code, make them explicit. 如果有活动之间的依赖关系在你的代码,使他们明确。 Otherwise, assume that they may occur in any order and may be interleaved. 否则,假设它们可能以任何顺序发生并且可能被交错。 That's the only sane way to program. 那是编程的唯一明智的方法。
And, finally, no. 最后,没有。 Once you've used a CancellationToken
, it's done. 使用CancellationToken
,就完成了。 If you need another one, you need to create a new one. 如果需要另一个,则需要创建一个新的。 This actually makes thinking about multiple tasks/activities simpler to think about - no token can go from being cancelled to being uncancelled. 实际上,这使考虑多个任务/活动变得更容易考虑-从取消令牌到取消令牌都不可能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.