了解多任务的异步/等待模式

Ugu*_*gur -1 c# multitasking async-await

目前,我很难理解使用异步和等待模式的多任务处理.为了测试一个案例,我编写了以下代码来理解一些基础知识;

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }

    private int global_int = 10;
    public async Task<int> RunAsyncTask()
    {
       // This method runs asynchronously.
       await Task.Run(() => Calculate());
       return global_int;
    }

    private int Calculate()
    {
        Console.WriteLine("Ticket count: " + --global_int);
        return global_int;
    }

    private async void  Start_Button_Click(object sender, RoutedEventArgs e)
    {
        List<Task<int>> list = new List<Task<int>>(); 

        Console.WriteLine("\nReseting: " );
        global_int = 10;

        for (int i = 0; i < 10; i++)
        {
            var task = RunAsyncTask();
            list.Add(task); 
        }

       await Task.WhenAll(list.ToArray<Task<int>>()); 

       Console.WriteLine("\nFinished: " + global_int);

    }
}
Run Code Online (Sandbox Code Playgroud)

理念/目标:

10个客户,10个门票,每个客户购买一张票,最后将没有可用的票.

问题:

当我运行代码时,我实际上并不总是得到相同的结果(总是期待0票).实际问题在哪里?

那么,我怎样才能以一种结果编写代码,结果总是相同的.

输出1:

Reseting: 
Ticket count: 9
Ticket count: 8
Ticket count: 8
Ticket count: 7
Ticket count: 5
Ticket count: 6
Ticket count: 4
Ticket count: 3
Ticket count: 2
Ticket count: 1

Finished: 1
Run Code Online (Sandbox Code Playgroud)

输出2:

Reseting: 
Ticket count: 9
Ticket count: 8
Ticket count: 7
Ticket count: 6
Ticket count: 5
Ticket count: 4
Ticket count: 3
Ticket count: 2
Ticket count: 1
Ticket count: 0

Finished: 0
Run Code Online (Sandbox Code Playgroud)

Jon*_*lis 6

--global_int
Run Code Online (Sandbox Code Playgroud)

这不是一个线程安全的操作.多个线程正在读写global_int,导致竞争状态.有一个方便的类叫做Interlocked来保持简单的int操作原子,将你的Calculate方法改为:

Console.WriteLine("Ticket count: " + Interlocked.Decrement(ref global_int);
Run Code Online (Sandbox Code Playgroud)

  • 我认为还应该注意这样一个事实:返回`global_int`可能会返回错误的值.最好在示例代码中显示检索Decrement调用的结果并返回(并可能记录),这比直接记录它更有用.返回`global_int`可能会获取另一个线程更改的值,而返回`Decrement`的结果应该总是得到当前线程生成的值(对吗?). (2认同)