2017-10-13 47 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(); 
    } 
} 
相关问题