[英]Calling a synchronous method in an async fashion?
我正在開發一個ASP.NET MVC WebApi項目,其中一種方法需要進行LDAP搜索。 搜索從LDAP服務器檢索到的信息量可確保呼叫至少花費7秒鍾才能完成。 該調用使用System.DirectoryServices.Protocols
類和方法,因此是同步的且不可修改。
該API將接收的流量非常大(即使該API在內部網絡中),因此對LDAP服務器的每次調用都需要7秒的時間不是一個好主意。 所以我想知道這一點:
await Task.Run(() => Search(params))
可以接受嗎?) 如評論中所述,我完全看不到使調用異步將如何幫助您。 在另一個線程中運行它並等待(按照您的“什么是正確的方法……”問題)確實使用了與同步調用和等待一樣多的資源。
但是請注意,諸如LdapCollection
類的System.DirectoryServices.Protocols
類確實具有對較早的APM(異步編程模型)樣式(例如BeginSendRequest
/ EndSendRequest
)的異步支持。
您可以使用TaskFactory<TResult>.FromAsync
輕松地將APM樣式的API包裝為可等待的基於任務的樣式,這是將這些類與async一起使用的“正確方法”。 另請參見與其他異步模式和類型互操作 。
PD:根據Lucero的回答,這是一個擴展方法,該方法隱藏APM調用並將其自身公開為常規Task<T>
異步方法:
public static async Task<DirectoryResponse> SendRequestAsync(this LdapConnection conn, string target, string filter,
SearchScope searchScope, params string[] attributeList)
{
if (conn == null)
{
throw new NullReferenceException();
}
var search_request = new SearchRequest(target, filter, searchScope, attributeList);
var response = await Task<DirectoryResponse>.Factory.FromAsync(
conn.BeginSendRequest,
(iar) => conn.EndSendRequest(iar),
search_request,
PartialResultProcessing.NoPartialResultSupport,
null);
return response;
}
這也可以用作您自己需要的起點(您可以使用類似的方法來“使”支持APM的對象以基於任務的樣式運行)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.