2016-06-20 4 views
0

zu laufen Ich habe ein paar Funktionen, die eine Benutzer-Antwort-Klasse bauen und ich bin immer noch die Aufgabe async erwarten.Wie mehrere Anrufe mit-in einer Funktion parallel

Aus dem unten stehenden Code gibt es eine Möglichkeit, all das parallel und nicht einzeln auszuführen?

Ich denke, meine erste Frage sollte sein, wie läuft der Anruf, wie er jetzt eingerichtet ist?

Meine zweite Frage ist, wie kann ich alle diese Anrufe parallel laufen?

Es ist nicht notwendig, dass die Rendite in einer bestimmten Reihenfolge zurückzukehren

public static async Task<ProjectForDrawings> GetProjectInfo(string cnn, int projectID) 
    { 

     return await Task.Run(() => 
     { 
      ProjectForDrawings projectForDrawings = DataBase.proc_GetProject_ForDrawings.ToRecord<ProjectForDrawings>(cnn, projectID); 

      projectForDrawings.Submittals = DataBase.proc_GetSubmittal.ToList(cnn, projectID); 

      projectForDrawings.ProjectLeafs = DataBase.proc_GetProjectLeafs.ToList<ProjectLeaf>(cnn, projectID); 

      projectForDrawings.Revisions = DataBase.proc_GetRevisionsForProject.ToList<Revisions>(cnn, projectID); 

      return projectForDrawings; 
     }); 
    } 

Antwort

1

, wie der Anruf stattfindet, wie es eingestellt ist nun?

Es plant die Arbeit an einem Hintergrundthread (Task.Run) und wartet dann asynchron für sie zu vollenden (await). Die Arbeit führt jeden Datenbankprozess nacheinander aus und blockiert den Hintergrund-Thread bis zum Abschluss synchron.

Wie kann ich all diese Anrufe parallel ausführen?

Sie alle Aufgaben beginnen und dann await sie alle mit Task.WhenAll:

public static async Task<ProjectForDrawings> GetProjectInfo(string cnn, int projectID) 
{ 
    ProjectForDrawings projectForDrawings = DataBase.proc_GetProject_ForDrawings.ToRecord<ProjectForDrawings>(cnn, projectID); 

    var submittalsTask = Task.Run(() => DataBase.proc_GetSubmittal.ToList(cnn, projectID)); 
    var leafsTask = Task.Run(() => DataBase.proc_GetProjectLeafs.ToList<ProjectLeaf>(cnn, projectID)); 
    var revisionsTask = Task.Run(() => DataBase.proc_GetRevisionsForProject.ToList<Revisions>(cnn, projectID)); 

    await Task.WhenAll(submittalsTask, leafsTask, revisionsTask); 

    projectForDrawings.Submittals = await submittalsTask; 
    projectForDrawings.ProjectLeafs = await leafsTask; 
    projectForDrawings.Revisions = await revisionsTask; 
    return projectForDrawings; 
} 

jedoch, viele (? Die meisten) Datenbanken nicht mehrere Anfragen pro Datenbankverbindung ermöglichen, so kann dies funktioniert nicht für Ihre Datenbank. Außerdem ist es möglicherweise keine gute Idee, Anrufe in der Datenbank an erster Stelle zu parallelisieren - es ist möglich, einen selbst auferlegten Denial-of-Service auszulösen. Schließlich, using Task.Run in the implementation is not a good pattern (aus Gründen, die ich in meinem Blog beschreibe) - natürliche Async-Methoden verwenden wäre besser.

+0

vielen Dank. –

+0

In diesem Artikel heißt es, dass 2005 und höher für SQL-Server gibt es einen Pool von Verbindungen und wenn ein Anrufer einen Aufruf an die Datenbank auf der gleichen Verbindung macht es greifen eine der verfügbaren Verbindungen und nutzen sie. Wenn es keine offene Verbindung gibt, wird dem Anrufer eine Reihe verfügbarer Verbindungen zur Auswahl angeboten. Das ist hier nur ein leises Gespräch, und ich verstehe das richtig? –

+0

@ AlumCloud.Com: Es hängt davon ab, wie die 'DataBase' Methoden implementiert sind. Wenn sie alle eine unabhängige 'DbConnection' verwenden, sollte das funktionieren. Wenn alle dieselbe DbConnection-Instanz verwenden, wird eine Ausnahme angezeigt. –