C#で非同期/並列実行を理解し、Stackoverflowでasync/awaitチュートリアルと解答を読むのに2日ほどかかりました。それでも私のコードで動作させることはできません。私は タスクの戻り値を使用するとInvalidCastExceptionが発生する
はWPF UIをブロックすることなく非同期PrincipalSearcherを通じて、Active Directoryの検索を実行して、必要なもの
。
実装_activeDirectoryの
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*/
{
...
}
}
クラス:
await
public PrincipalSearchResult<Principal> FindGroup(String pattern) { ... PrincipalSearchResult<Principal> searchResult = searcher.FindAll(); return searchResult; }
問題は、タスクが完了するのを待つていないようです。
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()
はおそらくそれが関連している場合でもタスクを返すでしょう。被験者全体はまだ私には霧がかかっています。
質問
- タスクが完了するのはなぜ
await
が待機しませんか? - 例外の理由は何ですか?
http://stackoverflow.com/questions/18110738/passing-collection-from-backgroundworker-dowork-to-backgroundworker-completed-an –
@Gosha_Fighten私はすでにしようとした 'PrincipalSearchResultのSearchResult =(PrincipalSearchResult )searchTaskを待ちます; '。これは問題を解決しませんでした。 –
mrplow