2014-12-19 76 views
0

我有一個要求功能A啓動一個較長時間運行的異步方法功能B(包括Web服務調用)。異步任務.Net 4.5

函數A應該返回,即使函數B還沒有返回。

函數B不返回任何數據,甚至當它調用函數的返回

使用.NET 4.5 C#,將最好的代碼是什麼應該執行,並且可以預見任何線程的問題?

.net上有很多例子,但是找到代碼的目的並不那麼簡單。

回答

1

函數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()發生的日誌記錄問題的好處。

+0

能夠登錄的好處是一個很好的獎勵! – 2014-12-19 02:28:34

+0

裏德,我使用你的擴展方法,但它只是掛在等待任務。我是否按照預期使用它? var t = new Task(()=> DoStuff()t。發射後不管(); – 2014-12-21 23:57:45

+0

在t.FireAndForget()之前添加對t.Start()的調用似乎有效.. – 2014-12-22 00:25:25

1

最簡單的方法是使用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拋出,否則會崩潰的過程。

+0

然後很簡單!即使A在B完成之前返回,這也應該起作用。 – 2014-12-19 00:24:05

+0

@SteveWard,是的; 'Task.Run'立即返回,而B繼續在單獨的線程上運行。 – 2014-12-19 00:26:49

+1

我認爲這不一定是一個很好的做法,尤其是因爲OP指出他們正在使用Web服務調用(異步IO).... – 2014-12-19 00:29:37