Make Method等待来自异步调用的结果

时间:2017-01-08 15:52:12

标签: c# asynchronous lync-client-sdk

如果这是基本的话,我对aysnc的理解有限,所以道歉。

我使用Lync SDK在我的方法中查询联系人,SDK使用异步来执行搜索并将结果返回到我的回调中。

我希望我的方法SearchForContact在获得所有结果后不会返回其调用者,但我不知道如何执行此操作。

感谢。

 public void SearchForContact(string search)
    {
        var searchFields = _LyncClient.ContactManager.GetSearchFields();

        object[] _asyncState = { _LyncClient.ContactManager, search };

        _LyncClient.ContactManager.BeginSearch(search, SearchProviders.GlobalAddressList | SearchProviders.ExchangeService
            , searchFields
            , SearchOptions.Default
            , 10
            , result =>
            {
                searchForContactResults = new List<MeetingContact>();

                SearchResults results = null;
                results = ((ContactManager)_asyncState[0]).EndSearch(result);
                if(results == null)
                    return;

                MeetingContact contactResult = new MeetingContact();

                foreach (var searchResult in results.AllResults)
                {
                    var c = searchResult.Result as Contact;

                    contactResult.FullName = c.GetContactInformation(ContactInformationType.DisplayName).ToString();
                    contactResult.SipAddress = c.Uri;  

                    searchForContactResults.Add(contactResult);

                }

                if (ResultOfSearchForContactEvent != null) ResultOfSearchForContactEvent(searchForContactResults); //returns results to subscriber fine, however I'd perfer not to do this
            }
            , _asyncState);

        //I want to return List<MeetingContact> here once BeginSearch has completed 

    }

编辑:

所以我基本上通过让线程休眠直到BeginSearch完成来完成它。必须有更好的方法吗?

public List<MeetingContact> SearchForContact(string search)
        {
            var searchFields = _LyncClient.ContactManager.GetSearchFields();

            object[] _asyncState = { _LyncClient.ContactManager, search };

            bool isComplete = false;

            _LyncClient.ContactManager.BeginSearch(search, SearchProviders.GlobalAddressList | SearchProviders.ExchangeService
                , searchFields
                , SearchOptions.Default
                , 10
                , result =>
                {
                    searchForContactResults = new List<MeetingContact>();

                    SearchResults results = null;
                    results = ((ContactManager)_asyncState[0]).EndSearch(result);
                    if(results == null)
                        return;

                    MeetingContact contactResult = new MeetingContact();

                    foreach (var searchResult in results.AllResults)
                    {
                        var c = searchResult.Result as Contact;

                        contactResult.FullName = c.GetContactInformation(ContactInformationType.DisplayName).ToString();
                        contactResult.SipAddress = c.Uri;  

                        searchForContactResults.Add(contactResult);

                    }

                    isComplete = true;

                }, _asyncState);

            while (isComplete == false)
            {
                Thread.Sleep(50);
            }

            return searchForContactResults;

        }

2 个答案:

答案 0 :(得分:0)

我永远不会推荐“阻止”。我建议使用async / await代替。要使用上面的示例执行此操作,请使用Task.Factory.FromAsync将异步方法转换为任务,然后等待它。

所以你的例子是:

public async Task<List<MeetingContact>> SearchForContact(string search)
{
    var searchFields = _LyncClient.ContactManager.GetSearchFields();
    var searchResults = await Task<SearchResults>.Factory.FromAsync((ar, o) => _LyncClient.ContactManager.BeginSearch(search, SearchProviders.GlobalAddressList | SearchProviders.ExchangeService, searchFields, SearchOptions.Default, 10, ar, o), _LyncClient.ContactManager.EndSearch, null);
    var searchForContactResults = new List<MeetingContact>();

    if (searchResults == null)
        return searchForContactResults;

    foreach (var searchResult in searchResults.Contacts)
    {
        var contactResult = new MeetingContact
        {
            FullName = searchResult.GetContactInformation(ContactInformationType.DisplayName).ToString(),
            SipAddress = searchResult.Uri
        };

        searchForContactResults.Add(contactResult);

    }

    return searchForContactResults;
}

如果你真的,真的必须阻止(我强烈反对)那么你所要做的就是放弃async / await并在任务上调用.Result如下:

public List<MeetingContact> SearchForContact(string search)
{
    var searchFields = _LyncClient.ContactManager.GetSearchFields();
    var searchResults = Task<SearchResults>.Factory.FromAsync((ar, o) => _LyncClient.ContactManager.BeginSearch(search, SearchProviders.GlobalAddressList | SearchProviders.ExchangeService, searchFields, SearchOptions.Default, 10, ar, o), _client.ContactManager.EndSearch, null).Result;
    var searchForContactResults = new List<MeetingContact>();

    if (searchResults == null)
        return searchForContactResults;

    foreach (var searchResult in searchResults.Contacts)
    {
        var contactResult = new MeetingContact
        {
            FullName = searchResult.GetContactInformation(ContactInformationType.DisplayName).ToString(),
            SipAddress = searchResult.Uri
        };

        searchForContactResults.Add(contactResult);

    }

    return searchForContactResults;
}

答案 1 :(得分:0)

要在搜索完成之前阻止,请尝试按以下方式调用BeginSearch()

SearchResults results = _LyncClient.ContactManager.EndSearch(_LyncClient.ContactManager.BeginSearch(search, SearchProviders.GlobalAddressList | SearchProviders.ExchangeService, searchFields, SearchOptions.Default, 10, null, _asyncState));

有关详细信息,请参阅:Asynchronous programming in Lync SDK