C# 什么时候我需要担心导致多线程的任务?

C# 什么时候我需要担心导致多线程的任务?,c#,.net,multithreading,asynchronous,async-await,C#,.net,Multithreading,Asynchronous,Async Await,假设我有这样的代码: ... var task1 = DoWorkAsync(1); var task2 = DoWorkAsync(2); await Task.WhenAll(task1, task2); ... private async Task DoWorkAsync(int n) { // Async HTTP request that we ConfigureAwait(to be determined). // Some CPU-bound work that

假设我有这样的代码:

...
var task1 = DoWorkAsync(1);
var task2 = DoWorkAsync(2);
await Task.WhenAll(task1, task2);
...

private async Task DoWorkAsync(int n)
{
    // Async HTTP request that we ConfigureAwait(to be determined).

    // Some CPU-bound work that isn't thread-safe.
}
因此,如果我在WPF应用程序中,并且没有对HTTP请求进行
ConfigureAwait(false)
,我在这里安全吗?这两个HTTP请求可以同时进行,但是任务必须在UI线程上恢复,所以CPU绑定的工作不是多线程的?但是如果我执行了
ConfigureAwait(false)
,任务可以在不同的线程池线程上并行恢复其CPU限制的工作,所以我有麻烦了

如果我在ASP.NET中,这两种情况都可能发生,因为同步上下文与WPF之类的线程没有任何关系

如果我在一个控制台应用程序中呢

如何谈论
DoWorkAsync
?我是说“同时执行
doworksync
s是不安全的”吗

有没有正常的方法来重新设计它?并发执行的重要部分是HTTP请求,而不是CPU绑定的工作,所以我是否使用锁或其他东西(以前从未使用过)

因此,如果我在WPF应用程序中,并且没有在HTTP请求上配置Await(false),那么我在这里安全吗

如果这是在UI线程上调用的,那么是的,您是正确的。UI上下文一次只允许一个线程(具体来说是UI线程),因此CPU绑定部分将在UI线程上运行,并且不会相互干扰。这是一个相当常见的伎俩

如果我执行ConfigureAwait(false),那么这些任务可以在不同的线程池线程上并行恢复其CPU限制的工作,所以我遇到了麻烦

对。因为
ConfigureAwait(false)
意味着“CPU绑定的工作不需要上下文”,所以它可以在线程池上并行运行

如果我在ASP.NET中

经典的ASP.NET有一个一次一个线程的请求上下文,所以它的行为是相同的;如果没有
configurewait(false)
,则是安全的

ASP.NET核心没有请求上下文(无论如何,也不是
SynchronizationContext
),因此它可以在该平台上并行运行。我称之为

如果我在一个控制台应用程序中呢

没有上下文,因此可以并行运行

如何谈论DoWorkAsync

“此方法需要非自由线程的
SynchronizationContext

我用锁还是别的什么

这是最好的方法,是的:

private readonly object _mutex = new object();
private async Task DoWorkAsync(int n)
{
  await HttpRequestAsync().ConfigureAwait(false);
  lock (_mutex)
  {
    // Some CPU-bound work that isn't thread-safe.
  }
}

以上代码是用于服务器端还是客户端?将来,请每个问题问一个问题。@LeiYang:以上代码用于一个类库,可以在这三种上下文(WPF、ASP.NET、console)中的任何一种中使用,我想是吧。令人惊讶的是,我的问题“太宽泛”了,无法得到“充分”的回答,而斯蒂芬却完全简洁地为我澄清了一切,对吧,伙计们?