2017-10-13 1 views
0

Ich habe über Async gelesen/warte vor kurzem und ich würde gerne wissen, wie man Daten zwischen verschiedenen Threads teilt, die zu verschiedenen Klassen gehören? Nehmen wir an, wir haben die HttpContext in einer Webanwendung. Dieser Kontext enthält Informationen über userId, sessionId und so weiter. Unsere Webanwendung liefert einige Daten, die von einer Konsolenanwendung verwendet werden, die auf einem anderen Computer ausgeführt wird. Wenn Fehler in dieser Konsolenanwendung auftreten, schreibe ich sie in eine Protokolldatei. userId und sessionId sollten auch in diese Protokolldatei geschrieben werden. Jeder in dieser Konsolenanwendung erstellte Thread hat jedoch einen eigenen Kontext. Also, ich bin auf der Suche nach einer Möglichkeit, userId und sessionId zu Thread-Kontext zu setzen. Ich möchte keine statischen Klassen oder volatile Felder verwenden. Ich gebe ein einfaches Beispiel meiner Konsolenanwendung unten an.Wie teile ich Daten zwischen verschiedenen Threads, die zu verschiedenen Klassen gehören?

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

Themen gehören nicht zu den Klassen. Ihr Code verwendet keine Threads, er verwendet asynchrone Methoden. Es ist keine Cross-Thread-Synchronisation erforderlich - wait stellt sicher, dass die Ausführung im richtigen Kontext fortgesetzt wird. Es sei denn, du blockierst es natürlich mit dem 'searchService.ExecuteSearchAsync(). Wait();' was bedeutet, dass no 'wait' zurückgeben kann –

+2

Nicht ganz sicher, was du versuchst zu tun, aber es klingt wie du es kannst indem Sie einfach userID und sessionId als Methodenparameter übergeben – mikelegg

+0

Was ist Ihre Frage? Was versuchst du zu machen? Hast du ein tatsächliches Problem festgestellt? Das einzige Problem in diesem Code ist 'public void Execute()' und der Aufruf von 'Wait()'. Die Methode sollte asynchron sein –

Antwort

1

Es ist fast nie notwendig, dass Daten 'auf den Thread-Kontext' gesetzt werden, also legen Sie das aus Ihrem Kopf.

Es ist gut, dass Sie Thread-Sicherheit in Betracht ziehen - die meisten Probleme kommen, weil die Leute nicht. Allerdings gibt es in diesem Fall besteht keine Notwendigkeit, aus 2 Gründen:

  1. von dem, was Sie sagen, userId und sessionId nicht während des Leben dieses Beispiels ändern. Viele Anfragen zur gleichen Zeit laufen könnten, aber jeder Stapel wird seine eigene Benutzer-ID haben/Sitzungs

  2. Ich wette, Benutzer-ID/sessionid sind unveränderlich Typen - also nicht geändert werden. Dies ist der Fall, wenn es sich um Strings oder Ints oder um einen beliebigen Wert handelt.

Also in diesem Sinn könnte man dies tun:

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