以异步方式调用同步方法?

Calling a synchronous method in an async fashion?

我正在开发一个 ASP.NET MVC WebApi 项目,其中一种方法需要进行 LDAP 搜索。搜索从 LDAP 服务器检索的信息量确保调用至少需要 7 秒才能完成。该调用使用 System.DirectoryServices.Protocols 类 和方法,是同步且不可修改的。

此 API 将接收的流量相当大(即使 API 在内部网络中)因此每次调用 LDAP 服务器 7 秒不是一个好主意.所以我想知道这个:

如评论中所述,我完全看不出使调用异步会有什么帮助。 运行 它在另一个线程中等待(根据您的 "what is the proper way..." 问题)确实使用了与同步调用和等待一样多的资源。

但是请注意,System.DirectoryServices.Protocols 类 例如 LdapCollection 确实支持旧的 APM(异步编程模型)样式(例如 BeginSendRequest/EndSendRequest) .

您可以使用 TaskFactory<TResult>.FromAsync, this would be the "proper way" of using these classes with async. See also Interop with Other Asynchronous Patterns and Types.

轻松地将 APM 样式的 API 包装为可等待的基于任务的样式

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;
}

这也可以作为满足您自己需求的起点(您可以使用类似于 "make" APM 支持对象以基于任务的方式运行的方法)。