簡體   English   中英

以異步方式調用同步方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM