C# 在等待MVC控制器操作之后,MVC请求线程状态为何以及如何维护?

C# 在等待MVC控制器操作之后,MVC请求线程状态为何以及如何维护?,c#,asp.net-mvc,async-await,C#,Asp.net Mvc,Async Await,在下面的代码中,线程id和_uow(工作单元)的散列在调用wait前后是相同的。如果请求线程被释放,为什么延续请求线程具有相同的id?为什么与请求线程关联的_uow对象具有相同的散列id,就像线程状态被维护一样,尽管它已被释放到线程池中 public AccountController(IUow uow) { _uow = uow; } public async Task<ActionResult> Sample() { int id1 = Thread.Curre

在下面的代码中,线程id和_uow(工作单元)的散列在调用wait前后是相同的。如果请求线程被释放,为什么延续请求线程具有相同的id?为什么与请求线程关联的_uow对象具有相同的散列id,就像线程状态被维护一样,尽管它已被释放到线程池中

public AccountController(IUow uow)
{
    _uow = uow;
}

public async Task<ActionResult> Sample()
{
    int id1 = Thread.CurrentThread.ManagedThreadId;
    int hash1 = _uow.GetHashCode();

    await SignInAsync(account, isPersistent: false);

    int id2 = Thread.CurrentThread.ManagedThreadId; //same as id1
    int hash2 = _uow.GetHashCode(); //same as hash1

    return Content("");
}
公共帐户控制器(IUow uow)
{
_uow=uow;
}
公共异步任务示例()
{
int id1=Thread.CurrentThread.ManagedThreadId;
int hash1=_uow.GetHashCode();
等待信号同步(帐户,ispersist:false);
int id2=Thread.CurrentThread.ManagedThreadId;//与id1相同
int hash2=_uow.GetHashCode();//与hash1相同
返回内容(“”);
}

这里可能有两种情况

  • SignInAsync
    已同步执行。请尝试以下操作,以了解情况是否如此:

    public async Task<ActionResult> Sample()
    {
        int id1 = Thread.CurrentThread.ManagedThreadId;
        int hash1 = _uow.GetHashCode();
    
        var task = SignInAsync(account, isPersistent: false);
        Debug.Print("completed synchronously: " + task.IsCompleted);
        await task;    
    
        int id2 = Thread.CurrentThread.ManagedThreadId; //same as id1
        int hash2 = _uow.GetHashCode(); //same as hash1
    
        return Content("");
    }
    
    公共异步任务示例()
    {
    int id1=Thread.CurrentThread.ManagedThreadId;
    int hash1=_uow.GetHashCode();
    var任务=符号同步(帐户,isPersistent:false);
    Debug.Print(“同步完成:+task.IsCompleted”);
    等待任务;
    int id2=Thread.CurrentThread.ManagedThreadId;//与id1相同
    int hash2=_uow.GetHashCode();//与hash1相同
    返回内容(“”);
    }
    
  • wait
    continuation之后,相同的池线程恰好服务于请求的其余部分。这是非常不可能的,但仍然是可能的,尽管你无论如何都不应该依赖它


在ASP.NET中,在
等待
之后,不能保证您在同一线程上。但这并不意味着你一定会在另一个线程上,你仍然可以偶然回到同一个线程。如果您正在等待的
任务在返回给您时已经完成,您也将保持在同一线程上

但是
\u uow
字段是另一回事:在该代码中始终保持不变(假设它不是
[ThreadStatic]
字段)。这是因为在
wait
之后,您总是返回到相同的
this
,它不绑定到任何线程


实际上,这一点更为强大:当前的
(以及与之相关的所有内容)也将保持不变。这是因为ASP.NET同步上下文将负责在
wait

之后将HTTP上下文移动到任何新线程,这似乎与同步上下文有关。我要读这些文章@Clive,
AspNetSynchronizationContext
不强制执行线程关联,反之亦然。一定要使用。