2014-04-10 24 views
1

在以下代码中,_uow(工作单元)的线程ID和哈希值在调用等待之前和之后是相同的。如果请求线程被释放,为什么继续请求线程具有相同的ID?为什么与请求线程关联的_uow对象具有相同的哈希ID,就像线程状态保持不变,尽管它被释放到线程池中?MVC请求线程状态为什么以及如何在等待MVC控制器动作后保持状态?

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(""); 
} 

回答

1

在ASP.NET中,您不能保证在await之后处于同一线程中。但这并不意味着你保证在另一个线程上,你仍然可以偶然地返回到同一线程。如果 ing已经完成并返回给您,您也将保持同一线程。

_uow字段是另一回事:它将始终保持在此代码中相同(假设它不是[ThreadStatic]字段)。这是因为在await之后,你总是会回到同样的this,这不会绑定到任何线程。

实际上,这个更强:HttpContext.Current(以及与之相关的所有东西)保持不变。这是因为ASP.NET同步上下文将负责在await之后将HTTP上下文移动到任何新线程。

1

这里可能有两种情况。

  • 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(""); 
    } 
    
  • 同一池中的线程发生的await后继续服务请求的其余部分。这是不太可能的,但仍然有可能,尽管你永远不应该依赖这个。

+0

似乎它与同步上下文有关。我将阅读这些文章。 http://blogs.msdn.com/b/pfxteam/archive/2012/01/20/10259049.aspx http://msdn.microsoft.com/en-us/magazine/gg598924.aspx – Clive

+0

@Clive,'AspNetSynchronizationContext '不强制执行线程关联,而是反之。确保你使用['UseTaskFriendlySynchronizationContext'](http://msdn.microsoft.com/en-us/library/hh975440.aspx)。 – Noseratio

相关问题