我花了差不多两天的时间阅读异步/等待教程和答案Stackoverflow和试图了解C#中的异步和并行执行。尽管如此,我还是无法让它与我的代码一起工作。InvalidCastException当使用任务返回值
我需要什么
执行通过PrincipalSearcher一个Active Directory搜索异步无阻塞的WPF界面。
实施
类 _activeDirectoryprotected 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*/
{
...
}
}
:
public PrincipalSearchResult<Principal> FindGroup(String pattern)
{
...
PrincipalSearchResult<Principal> searchResult = searcher.FindAll();
return searchResult;
}
问题
await
似乎并没有等待完成任务。searchTask.IsCompleted
在等待线之后是真实的,但它不能是因为几乎没有时间完成,如果我同步运行它,搜索需要大约5秒。- 如果在foreach循环的开始抛出的异常:
System.InvalidCastException occurred HResult=-2147467262
Message=Unable to cast COM object of type 'System.__ComObject' to interface type 'IDirectorySearch'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). Source=System.DirectoryServices StackTrace: at System.DirectoryServices.SearchResultCollection.get_SearchObject()
InnerException:
思考
- 我发现的是,这种异常的无效的SynchronizationContext是相关的,但我不知道看看这可能发生在这里。我还在几行代码上打印了Thread.CurrentThread.ManagedThreadId,它总是返回相同的ID。
- 我也读过,异步方法不应该返回
void
但Task<T>
,但我不认为这是相关的,因为没有人异步使用SearchButtonClick()。而且如果这个问题甚至相关的话,Task.Run()
可能会返回一个Task。整个主题对我来说依然模糊不清。
问题
- 为什么
await
不会等待任务完成? - 异常的原因是什么?
http://stackoverflow.com/questions/18110738/passing-collection-from-backgroundworker-dowork-to-backgroundworker-completed-an –
@Gosha_Fighten我已经试过'PrincipalSearchResult信息搜索结果=(PrincipalSearchResult )等待searchTask ;'。这并没有解决问题。 –
mrplow