2017-10-13 65 views
0

我在讀最近的異步/等待,我想知道如何共享屬於不同類的不同線程之間的數據?假設我們在某些Web應用程序中有HttpContext。此上下文包含有關userIdsessionId等的信息。我們的Web應用程序提供了一些在另一臺計算機上執行的控制檯應用程序使用的數據。如果在這個控制檯應用程序中發生錯誤,我會將它寫入日誌文件。 userIdsessionId也應寫入此日誌文件。但是在這個控制檯應用程序中創建的每個線程都有自己的上下文所以,我正在尋找一種方法將userIdsessionId設置爲線程上下文。我不想使用一些靜態類或volatile字段。我在下面放置了一個簡單的控制檯應用程序示例。如何在屬於不同類的不同線程之間共享數據?

public sealed class MainService 
    { 
     /// <summary> 
     /// The main method which is called. 
     /// </summary> 
     public void Execute() 
     { 
      try 
      { 
       searchService.ExecuteSearchAsync().Wait(); 
      } 
      catch (Exception e) 
      { 
       // gets additional info (userId, sessionId) from the thread context 
       StaticLoggerClass.LogError(e); 
      } 
     } 
    } 

    public sealed class SearchService 
    { 
     private IRepository repository = new Repository(); 

     public async Task ExecuteSearchAsync() 
     { 
      try 
      { 
       var result = await this.GetResultsAsync(); 
      } 
      catch (Exception e) 
      { 
       // gets additional info (userId, sessionId) from the thread context 
       StaticLoggerClass.LogError(e); 
      } 
     } 

     private async Task<ResultModel> GetResultsAsync() 
     { 
      var result = this.repository.GetAsync(); 
     } 
    } 

    public sealed class Repository 
    { 
     private IClient client; 

     public async Task<Entity> GetAsync() 
     { 
      return await client.GetResultAsync(); 
     } 
    } 
+0

線程不屬於類。你的代碼無論如何都不使用線程,它使用異步方法。沒有跨線程同步需要 - 等待確保執行將繼續在正確的上下文。除非你用searchService.ExecuteSearchAsync()來阻塞它,Wait();'這意味着沒有'await'能夠返回 –

+2

不太確定你想要做什麼,但它聽起來像你可以做到通過傳遞userId和sessionId作爲方法參數 – mikelegg

+0

您的問題是什麼?你想做什麼?你有沒有遇到實際問題?這個代碼中唯一的問題是public void Execute()和對Wait()的調用。該方法應該是異步的 –

回答

1

幾乎沒有必要將數據'設置到線程上下文',所以把它放在你的頭上。

這是很好,你正在考慮線程安全 - 大多數問題出現的原因是人們沒有。然而,在這種情況下,沒有必要有2個原因:

  1. 從你說的話,帳戶及的sessionId不要在 生活這個例子的過程中改變。許多請求可能在同一時間運行,但 每個堆棧將擁有自己的用戶ID /會話ID

  2. 我打賭用戶ID /會話ID是不可變的類型 - 即不能 改變。如果它們是字符串,整數或任何值,則是這種情況。

所以考慮到這一點,你可以這樣做:

public sealed class MainService 
{ 
    /// <summary> 
    /// The main method which is called. 
    /// </summary> 
    public void Execute() 
    { 
     try 
     { 
      // somehow get the userid/sessionid, you don't say where these are from 
      var userId = "?"; 
      var sessionId = "?" 

      searchService.ExecuteSearchAsync(userId, sessionId).Wait(); 
     } 
     catch (Exception e) 
     { 
      // gets additional info (userId, sessionId) from the thread context 
      StaticLoggerClass.LogError(e); 
     } 
    } 
} 

public sealed class SearchService 
{ 
    private IRepository repository = new Repository(); 

    public async Task ExecuteSearchAsync(string userId, string sessionId) 
    { 
     try 
     { 
      var result = await this.GetResultsAsync(); 
     } 
     catch (Exception e) 
     { 
      // gets additional info (userId, sessionId) from the thread context 
      StaticLoggerClass.LogError($"userId={userId}; sessionId={sessionId}; error={e}"); 
     } 
    } 

    // ........ 
    private async Task<ResultModel> GetResultsAsync() 
    { 
     var result = this.repository.GetAsync(); 
    } 
} 
相關問題