2016-07-27 26 views
-2

我需要採用I/O綁定的第三方函數,並在不創建後臺線程的情況下將其轉換爲等待狀態。此調用沒有本地異步方法。這是否可以在不創建後臺線程的情況下使同步庫函數等待?

這是我的理解,這將工作,但它會創建一個後臺線程,每次調用。

public string SomeSyncFunction() 
{ 
    Threading.Sleep(5000); 
    return "done"; 
} 

//awaitable but creates a background thread 
public Task<string> SomeSyncFunctionAsync() 
{ 
    return Task.Run(() => SomeSyncFunction()); 
} 

我相信這是沒有新線程的方式,但不完全確定。

public Task<string> SomeSyncFunctionAsync() 
{ 
    var tcs = new TaskCompletionSource<string>(); 
    try 
    { 
     tcs.SetResult(SomeSyncFunction()); 
    } 
    catch (Exception e) 
    { 
     tcs.SetException(e); 
    } 

    return tcs.Task; 
} 
+4

嗯,它並沒有真正使它異步。哎呀,你可以用'return Task.FromResult(SomeSyncFunction());'來簡化它,但它不會實現異步。你希望通過讓它保持等候狀態來實現什麼? –

+0

我假設目標是更好的響應。 –

+3

如果底層庫已經在進行阻塞調用(除了替換庫),後臺線程是最好的。 –

回答

1

「等待性」的要點是某些指令在後臺執行,允許您的代碼繼續進行。

你是什麼意思「使同步功能無需線程等待」?同步功能(與真正依賴硬件的異步功能相反)需要CPU運行,所以它需要一個線程。否則,如果它沒有新線程執行,那麼「awaitablility」沒有意義(它會阻塞)。 順便說一句,如果你關心繫統資源,那麼.Net任務機制不會產生新的系統線程,但重用已經爲任務創建的系統線程。

1

我需要採用I/O綁定的第三方函數,並在不創建後臺線程的情況下將其轉換爲等待狀態。此調用沒有本地異步方法。

這是不可能的,對不起。

您最好的選擇是聯繫第三方並要求他們提供異步API。在此期間,您將不得不保持同步API調用(如果您的應用程序是ASP.NET應用程序,或者調用代碼已經在非UI線程中),或者將同步API在Task.Run(如果它是從UI線程調用的)。

相關問題