【问题标题】:How to use Task.Factory.FromAsync with ldap library如何将 Task.Factory.FromAsync 与 ldap 库一起使用
【发布时间】:2020-02-28 11:13:44
【问题描述】:

我在网上找到了这门课:

public class AsyncSearcher
{
    LdapConnection _connect;

    public AsyncSearcher(LdapConnection connection)
    {
        this._connect = connection;
        this._connect.AutoBind = true; //will bind on first search
    }

    public void BeginPagedSearch(
            string baseDN,
            string filter,
            string[] attribs,
            int pageSize,
            Action<SearchResponse> page,
            Action<Exception> completed                
            )
    {
        if (page == null)
            throw new ArgumentNullException("page");

        AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(null);

        Action<Exception> done = e =>
            {
                if (completed != null) asyncOp.Post(delegate
                {
                    completed(e);
                }, null);
            };

        SearchRequest request = new SearchRequest(
            baseDN,
            filter,
            System.DirectoryServices.Protocols.SearchScope.Subtree,
            attribs
            );

        PageResultRequestControl prc = new PageResultRequestControl(pageSize);

        //add the paging control
        request.Controls.Add(prc);

        AsyncCallback rc = null;

        rc = readResult =>
            {
                try
                {
                    var response = (SearchResponse)_connect.EndSendRequest(readResult);
                    
                    //let current thread handle results
                    asyncOp.Post(delegate
                    {
                        page(response);
                    }, null);

                    var cookie = response.Controls
                        .Where(c => c is PageResultResponseControl)
                        .Select(s => ((PageResultResponseControl)s).Cookie)
                        .Single();

                    if (cookie != null && cookie.Length != 0)
                    {
                        prc.Cookie = cookie;
                        _connect.BeginSendRequest(
                            request,
                            PartialResultProcessing.NoPartialResultSupport,
                            rc,
                            null
                            );
                    }
                    else done(null); //signal complete
                }
                catch (Exception ex) { done(ex); }
            };


        //kick off async
        try
        {
            _connect.BeginSendRequest(
                request,
                PartialResultProcessing.NoPartialResultSupport,
                rc,
                null
                );
        }
        catch (Exception ex) { done(ex); }
    }

}

我基本上是在尝试将以下写入控制台的代码转换为从Task.Factory.FromAsync返回数据,以便我可以在其他地方使用数据。

using (LdapConnection connection = CreateConnection(servername))
        {
            AsyncSearcher searcher = new AsyncSearcher(connection);

            searcher.BeginPagedSearch(
                baseDN,
                "(sn=Dunn)",
                null,
                100,
                f => //runs per page
                {
                    foreach (var item in f.Entries)
                    {
                        var entry = item as SearchResultEntry;

                        if (entry != null)
                        {
                            Console.WriteLine(entry.DistinguishedName);
                        }
                    }

                },
                c => //runs on error or when done
                {
                    if (c != null) Console.WriteLine(c.ToString());
                    Console.WriteLine("Done");
                    _resetEvent.Set();
                }
            );

            _resetEvent.WaitOne();
            
        }

我试过了,但出现以下语法错误:

            LdapConnection connection1 = CreateConnection(servername);
            AsyncSearcher1 searcher = new AsyncSearcher1(connection1);


            async Task<SearchResultEntryCollection> RootDSE(LdapConnection connection)
            {
                return await Task.Factory.FromAsync(,

                        () =>
                            {
                                return searcher.BeginPagedSearch(baseDN, "(cn=a*)", null, 100, f => { return f.Entries; }, c => { _resetEvent.Set(); });
                            }
                        );
            }

            _resetEvent.WaitOne();

【问题讨论】:

    标签: c# async-await ldap task-parallel-library openldap


    【解决方案1】:

    The APM ("Asynchronous Programming Model") style of asynchronous code uses Begin and End method pairs along with IAsyncResult, following a specific pattern.

    The Task.Factory.FromAsync method is designed to wrap APM method pairs into a modern TAP ("Task-based Asynchronous Programming") style of asynchronous code.

    然而,FromAsync要求方法遵循 APM 模式完全,而BeginPagedSearch 不遵循 APM 模式。所以你需要直接使用TaskCompletionSource&lt;T&gt;TaskCompletionSource&lt;T&gt; can be used to convert any existing asynchronous pattern to TAP 只要它有一个结果。

    你试图包装的方法有多个回调,所以它根本不能映射到TAP。如果您想收集所有个结果集并返回它们的列表,那么您可以使用TaskCompletionSource&lt;T&gt;。否则,您将需要使用 IAsyncEnumerable&lt;T&gt; 之类的东西,这需要编写您自己的 BeginPagedSearch 实现。

    【讨论】:

      猜你喜欢
      • 2016-09-04
      • 1970-01-01
      • 2016-12-24
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      • 2011-01-23
      • 1970-01-01
      相关资源
      最近更新 更多