2016-07-14 12 views
2

Das Entitätsframework importiert gespeicherte Prozeduren als Methoden für Ihre DbContext-Klasse. Sie sind jedoch nicht asynchron und ich möchte in der Lage sein, diese von einem asynchronen WebApi-Controller aufzurufen, ohne den Thread zu blockieren. Ich habe eine asynchrone Wrapper-Methode geschrieben, aber ich bin verwirrt von einer Warnung, die Visual Studio mir gibt.Asynchron synchroner Code

Wird dieser Code asynchron ausgeführt?

public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId) 
    { 
     await Task.Run(() => 
     { 
      //synchronous method generated by EF. 
      //VS warning here 
      AttachTypeToMeetingTime(meetingTimeId, meetingTypeId); 
     }); 
    } 

Visual Studio gibt mir die Warnung:

Da dieser Anruf nicht erwartet wird, wird die Ausführung des aktuellen Threads fort, bevor der Anruf

abgeschlossen ist

jedoch Wenn ich den Vorschlag folgen und add have es ist rot unterstrichen und wird nicht kompiliert.

Soll der aktuelle Thread nicht fortgesetzt werden, bevor der Anruf beendet wird?

+0

Randbemerkung: Ich hoffe, Sie verstehen, dass das, was Sie versuchen, tatsächlich nur die Leistung verringert sich zu tun - statt einem Thread von Threadpool mit Anforderung bearbeitet Sie jetzt Arbeit zu einem anderen Thread-Pool-Thread verschieben und für Kontextwechsel/Thread zahlen Synchronisierung (zusätzlich wird dieser Thread auch nicht mit Kultur/Aktueller Anfrage eingerichtet und wird Ihnen alle Arten von Spaß später geben) –

+0

@AlexeiLevenkov Tut mir leid, ich habe das vorher gesehen und ich nahm an, es war in Ordnung. Der Auflösungsteil wurde auf seine eigene Antwort verschoben. Was macht ich anders als asynchrone Controller-Methoden und/oder Vanilla-EF-Async-Methoden wie 'FindAsync()'? –

+0

Wahre asynchrone Methoden warten nicht auf einen Thread (anders als einmal synchron). Vielleicht möchten Sie über async im Allgemeinen lesen, sollte ich asynchrone Wrapper für synchrone Methoden verfügbar machen? (Http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) ist eins Startpunkt. –

Antwort

4

Sie führen einen rekursiven Aufruf durch. Ich glaube nicht, dass du das wolltest.

Es sollte eine synchrone Methode, wie Sie sagten, anstelle von AttachTypeToMeetingTime aufrufen.

public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId) 
{ 
    await Task.Run(() => 
    { 
     SomeMethod(meetingTimeId, meetingTypeId); 
     ^^^^^ 
    }); 
} 
+0

Guter Fang auf der Rekursion – BradleyDotNET

+0

es war ein Tippfehler, danke, dass Sie das fangen. Ich habe die Frage bearbeitet. –

1

Ich rief den Methodennamen falsch an. Es sollte sein:

public async Task AttachTypeToMeetingTimeAsync(int meetingTimeId,int meetingTypeId) 
    { 
     await Task.Run(() => 
     { 
      //synchronous method generated by EF. 
      //VS warning here 
      AttachTypeToMeetingTime(meetingTimeId, meetingTypeId); 
     }); 
    } 

Die Signatur für die generierte Methode

AttachTypeToMeetingTime(int? meetingTimeId,int? meetingTypeId) 

war ich dachte, dass da meine Methode der Parameter int waren und die Parameter der erzeugten Methode waren int?, dass die Unterschriften nicht kollidieren würden, aber ich Raten Sie, dass visual Studio suggestive Engine und vielleicht der Compiler.

0

Füllen Sie die Inhalte, die mit "Your" beginnen, im folgenden Code aus.

public async Task AttachTypeToMeetingTime(int meetingTimeId,int meetingTypeId) 
{ 
    using(var context = new YourContext()) 
    { 
     await conext.Database.ExecuteSqlCommandAsync("YourStoredProcedureName @YourParam1Name, @YourParam2Name", meetingTimeId, meetingTypeId); 
    } 
}