I have spend almost two days reading async/await tutorials and answers on Stackoverflow and trying to understand asynchronous and parallel execution in C#. Still I can not get it to work with my code.
What I need
Execute a Active Directory search through PrincipalSearcher asynchronously without blocking the WPF UI.
Implementation
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*/
{
...
}
}
Class of _activeDirectory:
public PrincipalSearchResult<Principal> FindGroup(String pattern)
{
...
PrincipalSearchResult<Principal> searchResult = searcher.FindAll();
return searchResult;
}
Problem
await
does not seem to wait for the task to complete.searchTask.IsCompleted
is true after the await line, but it can't be because it takes almost no time to be completed and if I run it synchronously the search takes about 5s.- An exception if thrown at the beginning of the foreach loop:
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:
Thoughts
- What I found is that this kind of exception is related to invalid SynchronizationContext but I don't see how this could have happened here. I also printed Thread.CurrentThread.ManagedThreadId on several lines of codes and it always returned the same id.
- I also read that async methods should not return
void
butTask<T>
but I don't think this is relevant here because nobody is using SearchButtonClick() asynchronously. AndTask.Run()
probably does return a Task if that even relevant. The whole subject is still foggy to me.
Question
- Why does
await
not wait for the Task to complete? - What is the reason for the exception?