gpt4 book ai didi

c# - 使用任务返回值时出现 InvalidCastException

转载 作者:太空狗 更新时间:2023-10-30 01:01:41 26 4
gpt4 key购买 nike

我花了将近两天的时间阅读 Stackoverflow 上的异步/等待教程和答案,并尝试了解 C# 中的异步和并行执行。我仍然无法让它与我的代码一起工作。

我需要什么

在不阻塞 WPF UI 的情况下通过 PrincipalSearcher 异步执行 Active Directory 搜索。

实现

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 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不等待任务完成?
  • 异常的原因是什么?

最佳答案

await 是否等待 Task去完成。使用 async\await 模式和 TPL 库时,您唯一错过的是 Exception 被抛出 inside Task在那一刻没有被正确抛出。它被缓存在 ExceptionTask 的属性,并在您想要获得它的结果后立即抛出。

所以问题是你在 Task 中运行的代码, 正如@NineBerry 所说,不能进入另一个线程。您必须在 Task内部创建您的AD-对象,像这样:

Task<PrincipalSearchResult<Principal>> searchTask = Task.Run(() =>
{
// this have to be a local variable inside your task
var _activeDirectory = GET_THE_AD();
return _activeDirectory.FindGroup(searchText.Text));
}

或者,您可能每次都必须为线程创建 searcher 变量。

关于c# - 使用任务返回值时出现 InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37515121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com