【发布时间】:2016-09-27 15:52:05
【问题描述】:
我花了将近两天时间阅读有关 Stackoverflow 的 async/await 教程和答案,并尝试了解 C# 中的异步和并行执行。我仍然无法让它与我的代码一起使用。
我需要什么
通过 PrincipalSearcher 异步执行 Active Directory 搜索,而不阻塞 WPF UI。
实施
protected async void SearchButtonClick()
{
Task<PrincipalSearchResult<Principal>> searchTask = Task.Run(() => _activeDirectory.FindGroup(searchText.Text));
PrincipalSearchResult<Principal> searchResult = await searchTask;
foreach (var foundGroup in searchResult) /*exception thrown here*/
{
...
}
}
_activeDirectory 的类:
public PrincipalSearchResult<Principal> FindGroup(String pattern)
{
...
PrincipalSearchResult<Principal> searchResult = searcher.FindAll();
return searchResult;
}
问题
-
await似乎没有等待任务完成。searchTask.IsCompleted在 await 行之后是真的,但它不可能是因为它几乎不需要时间来完成,如果我同步运行它,搜索大约需要 5 秒。 - 如果在 foreach 循环开始时抛出异常:
发生 System.InvalidCastException HResult=-2147467262
消息=无法将“System.__ComObject”类型的 COM 对象转换为 接口类型“IDirectorySearch”。此操作失败,因为 对具有 IID 的接口的 COM 组件上的 QueryInterface 调用 “{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}”由于以下原因而失败 错误:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE))。源 = System.DirectoryServices StackTrace: 在 System.DirectoryServices.SearchResultCollection.get_SearchObject()
内部异常:
想法
- 我发现这种异常与无效的 SynchronizationContext 有关,但我不明白这怎么可能发生在这里。我还在几行代码上打印了 Thread.CurrentThread.ManagedThreadId,它总是返回相同的 id。
- 我还读到异步方法不应该返回
void,而是返回Task<T>,但我认为这与这里无关,因为没有人异步使用 SearchButtonClick()。而Task.Run()probably 确实会返回一个任务,如果这甚至相关的话。整个主题对我来说仍然是模糊的。
问题
- 为什么
await不等待任务完成? - 异常原因是什么?
【问题讨论】:
-
@Gosha_Fighten 我已经尝试过
PrincipalSearchResult<Principal> searchResult = (PrincipalSearchResult<Principal>) await searchTask;。这并没有解决问题。
标签: c# multithreading active-directory async-await task-parallel-library