2017-01-08 16 views
0

私はaysncの理解が限られているので、これが基本的であれば謝ります。メソッドが非同期呼び出しの結果を待つ

私のメソッドで連絡先を照会するのにLync SDKを使用していますが、SDKはasyncを使用して検索を行い、結果をコールバックに返します。

私のメソッド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 

    } 

EDIT:

ので、私は基本的に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; 

     } 
+0

このメソッドを非同期に呼び出し、結果を待たずにしますか? –

+0

@Romaこのメソッドが – Damo

+0

を返す前に "_LyncClient.ContactManager.BeginSearch"を終了したいと思います@Damo SearchForContactsは最初のソースのようにvoidを返す必要があります。リストをファイルする必要があります。 。このリストを消費するのは何ですか?それを非同期に変換することができます。また、バグがあります。何もないとき( 'results == null')が返され、ループは無限であるときにisCompleteを設定していません。 –

答えて

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

あなたは本当に、本当に(私は強く反論する)ブロックするようにしている場合、あなたがしなければならないすべては/が待つ非同期をドロップし、上.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; 
} 
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

関連する問題