我有一個要求功能A啓動一個較長時間運行的異步方法功能B(包括Web服務調用)。異步任務.Net 4.5
函數A應該返回,即使函數B還沒有返回。
函數B不返回任何數據,甚至當它調用函數的返回
使用.NET 4.5 C#,將最好的代碼是什麼應該執行,並且可以預見任何線程的問題?
.net上有很多例子,但是找到代碼的目的並不那麼簡單。
我有一個要求功能A啓動一個較長時間運行的異步方法功能B(包括Web服務調用)。異步任務.Net 4.5
函數A應該返回,即使函數B還沒有返回。
函數B不返回任何數據,甚至當它調用函數的返回
使用.NET 4.5 C#,將最好的代碼是什麼應該執行,並且可以預見任何線程的問題?
.net上有很多例子,但是找到代碼的目的並不那麼簡單。
函數A應該返回,即使函數B還沒有返回。
在這種情況下,關鍵是你不應該await
電話B
。
啓動一個較長時間運行的異步方法函數B(包括Web服務調用)。
在一般情況下,如果操作的大部分是Web服務調用,您應該不使用Task.Run
。 Task.Run將在後臺線程上執行該工作,這可能不是必需的,因爲您可以使用異步IO。
取而代之,創建您的方法async Task B()
,使用方法內的正常的await
機制,並調用它。默認情況下,這將導致編譯器警告,但您可以通過創建一個記錄發生的異常的擴展方法來解決此問題。
這可以是簡單:
public static async void FireAndForget(this Task task)
{
try
{
await task;
}
catch (Exception e)
{
// Log the exception
}
}
這也提供了內B()
發生的日誌記錄問題的好處。
最簡單的方法是使用Task.Run
,這對一個新的線程執行操作:
public void A()
{
// Do something...
Task.Run(B);
// or, if you need to pass arguments to B:
// Task.Run(() => B(x, y, z));
// Do something else...
}
public void B()
{
// Do something...
}
要小心,不要讓任何異常進行的B拋出,否則會崩潰的過程。
然後很簡單!即使A在B完成之前返回,這也應該起作用。 – 2014-12-19 00:24:05
@SteveWard,是的; 'Task.Run'立即返回,而B繼續在單獨的線程上運行。 – 2014-12-19 00:26:49
我認爲這不一定是一個很好的做法,尤其是因爲OP指出他們正在使用Web服務調用(異步IO).... – 2014-12-19 00:29:37
能夠登錄的好處是一個很好的獎勵! – 2014-12-19 02:28:34
裏德,我使用你的擴展方法,但它只是掛在等待任務。我是否按照預期使用它? var t = new Task(()=> DoStuff()t。發射後不管(); – 2014-12-21 23:57:45
在t.FireAndForget()之前添加對t.Start()的調用似乎有效.. – 2014-12-22 00:25:25