8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

当多个 C# 任务在另一个任务完成时启动时会发生什么?

blogofsongs 3月前

81 0

假设我有以下代码:public async void Run(){ TaskCompletionSource t = new TaskCompletionSource(); Prepare(t.Task); await Task.Delay(1000); t.SetResult(); Console.

假设我有这样的代码:

public async void Run()
{
    TaskCompletionSource t = new TaskCompletionSource();
    Prepare(t.Task);
    await Task.Delay(1000);

    t.SetResult();
    Console.WriteLine("End");
}

public async void Prepare(Task task)
{
    await Run(task, "A");
    await Run(task, "B");
    await Run(task, "C");
    await Run(task, "D");
}

public async Task Run(Task requisite, string text)
{
    await requisite;
    Console.WriteLine(text);
}

时会发生什么 t.SetResult(); ?这是多线程吗?控制台中项目的顺序有任何保证吗?如果我有一个 List<> ,并且该 Run 方法会改变它,我需要担心多线程吗?

帖子版权声明 1、本帖标题:当多个 C# 任务在另一个任务完成时启动时会发生什么?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由blogofsongs在本站《multithreading》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 这在很大程度上取决于应用程序处理的吞吐量 - 如果流量很大,则可能涉及多个线程。

    但一般来说, Task 使用 async / await 并不保证多线程,当需要时才会使用新线程(来自线程池) - 当前线程正忙于某些工作并且无法承担新的工作。

    异步执行的想法是,当有工作需要等待时(我们的处理器必须等待某些事情,比如 I/O 操作),它会释放当前线程并让其执行其他工作。

    这样,一个线程可能正在“并行”执行两个任务。但这是多任务,而不是多线程。

    有了这些知识,让我们来分析您的代码。

    首先,您创建 TaskCompleti完成Source 具有 Task “正在进行”并且可以等待的 - 但是一旦我们调用它,它就会 SetResult on TaskCompletionSource .

    然后我们调用 Prepare ,我们并不等待,但它等待传递的 Task ,因此此执行路径将停止 await Run(task, "A") 并等待任务完成,这将在我们调用时发生 SetResult (如前所述)。之后 Prepare (因此任务已经在等待中),我们调用 await Task.Delay - 我们这里还有另一个 await ,这次是为了延迟。由于我们使用 Task s ,因此不会创建新线程,因为 await Run 只是等待,线程可以继续进行其他工作并将处理代码的执行。因此,等待延迟和等待任务将并行、异步完成。

    然后,当延迟完成时,它将设置任务的结果,这意味着 await Run(task, "A") 将获得\'解除阻塞\',打印结果并继续 await Run(task, "B") ,但这将尝试等待已经完成的任务,因此它将同步执行(任务已经完成,没有什么可等待的),立即打印\'B\',然后\'C\',然后\'D\'(按顺序)。

    您可能会遇到一个问题 - 您的程序可能会在 Prepare 方法中的所有任务完成之前完成 - 因为它是 async void ,我们无法等待它。我建议进行一些小改进:

    public async void Run()
    {
        TaskCompletionSource t = new TaskCompletionSource();
        var prepareTask = Prepare(t.Task);
        await Task.Delay(1000);
    
        t.SetResult();
        
        await prepareTask;
        
        Console.WriteLine("End");
    }
    
    public async Task Prepare(Task task)
    {
        await Run(task, "A");
        await Run(task, "B");
        await Run(task, "C");
        await Run(task, "D");
    }
    
    public async Task Run(Task requisite, string text)
    {
        await requisite;
        Console.WriteLine(text);
    }
    
返回
作者最近主题: