zu schreiben, könnte es eine dumme Frage sein. Ich überschreibe eine synchrone HTTP-Sendedatenfunktion zu asynchron mit TAP. Die Funktion sieht wie folgt aus:Korrekter Weg, um Sync-Funktion mit TAP
public void SendToUrl(string url, string content)
{
try
{
byte[] payload = Encoding.ASCII.GetBytes(content);
Stopwatch sw = Stopwatch.StartNew();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/plain";
request.ContentLength = payload.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(payload, 0, payload.Length);
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
sw.Stop();
if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Accepted)
{
....
}
else
{
....
}
}
}
catch // error handling omitted
{
}
}
Zunächst Ich denke, es ist sehr einfach, ersetzen Sie einfach alle Sync-Funktionen NET-Bibliothek mit ihren awaitable XXXAsync Kollegen und Änderungsfunktion Signatur public async void SendToUrlAsync(...)
(weil ich warten im Inneren nutzen die Funktion), aber nach dem Lesen einiger Artikel, es sieht aus wie viele Leute sagen async void
ist nicht sicher (konnte den gesamten Prozess abstürzen), und es ist nur für Event-Handler konzipiert. Synchronous Void-Funktion sollte in async Task
übersetzt werden, auch ich möchte hier eine Feuer-und-vergessen-Funktion. Wenn das wahr ist, um eine Aufgabe gewaltsam zurückzugeben, muss ich den ganzen Code innerhalb einer Task.Run(() => {...})
kapseln, die für mich redundant und seltsam aussieht, da ich mich wirklich nicht für das Rückgabe-Task-Objekt interessiere, aber wenn ich nicht darauf warte Compiler wird sich beschweren. Also, in meinem Fall, was ist der empfohlene Weg, um es neu zu schreiben? Vielen Dank.
Danke Stephen! Ihr Buch und Ihr Blog sind sehr hilfreich. Ich folgte Ihren Vorschlägen und fand, dass Sie Recht haben, mit Async-Schlüsselwort in der Signatur muss ich Task.Run nicht explizit aufrufen, um eine Aufgabe zu erstellen und zurückzugeben, glücklich, das zu lernen. Ich habe 2 Fragen: (1) Jetzt beschwert sich Compiler, dass ich meine neue Funktion SendToUrlAsync erwarten sollte, wenn ich Feuer-und-Vergessen-Verhalten haben möchte, was soll ich tun? (2) Können Sie etwas mehr über Stream.Write/Stream.WriteAsync erklären? Ich habe viele Beispiele gesehen, die Request-Streams auf diese Weise verwenden. Wenn dies nicht der Fall ist, was ist der richtige Weg, um Daten zu posten? Tks! – codewarrior
Ich habe versucht, hinzuzufügen, wenn Anrufer SendToUrlAsync, jetzt Compiler sagte, ich musste den Anrufer zu asynchronen Task ändern. Ich kann sehen, dass ich bald jede Funktion in dieser Aufrufkette zu async Task ändern muss, ist das ein guter Weg? – codewarrior
@codewarrior: Idealerweise ja, du solltest 'async' wachsen lassen. 1) Um Feuer-und-Vergessen zu machen (was [fast immer falsch] ist (http://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html)), tun Sie ' var _ = SendToUrlAsync(); '. 2) Verwende 'BinaryWriter' oder lege es in einen' MemoryStream' und rufe 'CopyToAsync' auf. –