如果这是基本的话,我对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;
}
答案 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