它可能是一個愚蠢的問題。我正在用TAP重寫同步HTTP發送數據函數以異步。 功能如下:正確的方式來重寫同步功能與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
{
}
}
起初,我認爲這是非常簡單的,只需更換與他們awaitable XXXAsync同行和變化的函數簽名的所有同步.NET庫函數來public async void SendToUrlAsync(...)
(因爲我用等待着裏面的函數),但是,在閱讀了一些文章之後,看起來好像很多人說async void
不安全(可能會導致整個進程崩潰),而且它僅用於事件處理程序。同步無效函數應該被翻譯成async Task
,即使我想在這裏有一個失火和遺忘的函數。 如果這是真的,爲了強制返回一個任務,我需要封裝整個代碼Task.Run(() => {...})
這看起來像多餘和奇怪,因爲我真的不關心返回任務對象,但如果我不等待它編譯器會抱怨。 那麼,在我的情況下,推薦重寫它的方法是什麼?謝謝。
謝謝Stephen!你的書和你的博客是超級有用的。我遵循你的建議,並發現你是正確的,在簽名中使用async關鍵字,我不需要顯式調用Task.Run來創建並返回任務,很高興能夠學習這一點。我有兩個問題:(1)現在,編譯器抱怨說我應該等待我的新函數SendToUrlAsync,如果我確實想要失控行爲,我該怎麼辦? (2)你能解釋一下關於Stream.Write/Stream.WriteAsync的更多信息嗎?我看到很多以這種方式使用請求流的示例,如果它不正確,發佈數據的正確方法是什麼? TKS! – codewarrior
我試圖在調用者調用SendToUrlAsync時添加await,現在編譯器說我需要將調用者更改爲異步Task。我可以看到,很快我需要將此調用鏈中的每個函數都改爲異步任務,這是一個好方法嗎? – codewarrior
@codewarrior:理想情況是,你應該讓'async'成長。 1)要做到隨心所欲(這是[幾乎總是錯](http://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html)),做' var _ = SendToUrlAsync();'。 2)使用'BinaryWriter'或將其放入'MemoryStream'並調用'CopyToAsync'。 –