2016-07-27 23 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线程调用的)。

相关问题