在我的 WCF 服務中,我必須呼叫一個 API,我想在其中執行 Fire and Forget 實作。如果可能的話,只要捕獲錯誤(如果有的話)。(這也很好,如果不是一個選項)
我計劃進行以下實施,它可能導致什么問題?通過執行以下實作將留下大量打開的連接。或者可能是什么問題?請幫助理解如何以更好的方式實作這一點。
void SendRequest(inputs)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/xml";
byte[] requestBytes = Encoding.UTF8.GetBytes(inputXML);
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestBytes, 0, requestBytes.Length);
}
request.GetResponseAsync();
}
Main()
{
try
SendRequest(inputs);
catch ex
log ex;
}
uj5u.com熱心網友回復:
首先,制作代碼的完全異步版本
using System.Threading;
public async Task<System.Net.WebResponse> SendRequestAsync(
string inputXML, string url, CancellationToken cancellationToken)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/xml";
byte[] requestBytes = Encoding.UTF8.GetBytes(inputXML);
// GetRequestStreamAsync is a lightweight operation I assume
// so we don't really need any cancellation
using (Stream requestStream = await request.GetRequestStreamAsync())
{
// Idk if we really need cancellation here, but just in case of big request we might need to
await requestStream.WriteAsync(
requestBytes, 0, requestBytes.Length, cancellationToken);
}
// Close any long-running request
using (cancellationToken.Register(() => request.Abort(), useSynchronizationContext: false))
{
var response = await request.GetResponseAsync();
cancellationToken.ThrowIfCancellationRequested();
return response;
}
}
讓我們創建一個async void方法,但要確保它安全。它將基本上以“即發即棄”的方式執行。
public async void DoWork(string inputXML, string url, CancellationToken ct)
{
try
{
using(var response = await SendRequestAsync(inputXML, url, ct))
{
var httpResponse = (HttpWebResponse) response;
// Use 201 Created or whatever you need
if (httpResponse.StatusCode != HttpStatusCode.Created)
{
// TODO: handle wrong status code
}
}
}
catch (Exception e)
{
if (ct.IsCancellationRequested)
{
Console.WriteLine("Cancelled");
}
else
{
// TODO: handle exception
}
}
}
private static CancellationTokenSource _cts = new CancellationTokenSource();
public static void Main (string[] args)
{
DoWork("xml string", "example.com", cts.Token);
Console.WriteLine("Boom!");
if (Console.ReadLine() == "exit")
{
// Cancel the damn job
cts.Cancel();
}
}
從內部處理所有錯誤很重要 a DoWork,因為以下將不起作用
// Warning, will NOT catch an exception
public static void Main (string[] args)
{
try
{
DoWork("xml string", "example.com");
}
catch (Exception e)
{
}
}
編輯: OP 要求取消,所以我添加了取消
uj5u.com熱心網友回復:
請注意,最好不要使用即發即棄,特別是如果這是應用程式的核心層并且您可能會錯過重要的例外情況。當您使用此技術時,您必須記住會發生以下情況:
- 例外將默默地失敗,沒有任何機會抓住它們。通常你會想要記錄它們或收到通知。
- 你不知道代碼何時完成,
- 由于您不需要完成代碼并且它可能無法運行,因此您不會收到無法完成的通知。
使用此技術的一個很好的案例場景可能是更新快取,例如。
話雖如此,您可以使用以下技術:
NET 4.5 允許我們通過Task.Run
Task.Run(() => FireAndForget());
您還可以使用無引數 lambda 啟動執行緒:
(new Thread(() => {
FireAndForget();
}) {
Name = "Running Work Thread (FireAndForget)",
Priority = ThreadPriority.BelowNormal
}).Start();
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/416238.html
標籤:
