问题标签 [taskcompletionsource]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
816 浏览

c# - Force any task to be attached to parent

I'm trying to create an extension method that will make any task attached to parent.

Extension code:

Test Code:

Parent task is cancelled immediately without waiting for inner tasks to complete. How can I solve it, as an input I'm getting a task which I'm execution in my parent dispatcher task. I want to execute any task as attached to parent.

0 投票
2 回答
293 浏览

c# - 包装使用基于事件的异步模式的库,用于 Async/Await

我在整个代码中使用异步/等待模式。但是,有一个 API 使用了基于事件的异步模式。我在 MSDN 和几个 StackOverflow 上阅读过答案,这样做的方法是使用 TaskCompletionSource。

我的代码:

并称为:

或者,为了测试:

该方法总是很快返回,但没有一个事件被触发。

如果我添加 tcs.Task.Await(); 就在 return 语句之前,它可以工作,但这并没有提供我想要的异步行为。

我已经与我在互联网上看到的各种样本进行了比较,但没有发现任何差异。

0 投票
2 回答
388 浏览

c# - 如何将同步上下文/任务调度程序替换为 TaskCompletionSource.Task 中的另一个同步上下文/任务调度程序以获取 ConfigureAwait(false)?

假设我创建了一个包含此类方法的库:

我的 lib 的任何用户都可以MyLibraryMethodAsync这样调用

问题来了——VeryLongRunningMethod将在taskCompletionSource.SetResult(null)调用内部执行,因此它将阻塞workerThread很长一段时间,这是不希望的行为,因为workerThread它旨在运行一小部分代码(工作项)。

如何将上下文/调度程序替换为返回的任务中的线程await x.ConfigureAwait(false)以继续在线程池上,而不是在线程池上workerThread

我找到的当前解决方案是

但是,我不喜欢它,因为它会产生开销。可能存在更优雅的解决方案吗?

0 投票
1 回答
5343 浏览

c# - 模拟异步方法

我们正在使用 MSTest 和 Moq 为异步代码编写单元测试。

所以我们有一些看起来像这样的代码:

或者像这样在具有更新版本 Moq 的项目上

查看 ReturnsAsync 的 Moq 实现:

这两种方法在引擎盖下似乎是相同的。两者都创建一个TaskCompletionSource,调用SetResult并返回Task

到目前为止,一切都很好。

但是短期运行的async方法被优化为同步运行。这似乎意味着TaskCompletionSource始终是同步的,这似乎也表明上下文处理和任何可能发生的相关问题永远不会发生。

因此,如果我们有一些代码执行了一些async禁止操作,例如混合和awaits,那么在单元测试中就不会检测到这些问题。Wait()Result

创建一个总是产生控制权的扩展方法有什么好处吗?就像是 :

在这种情况下,我们将有一个保证异步执行的方法。

感知到的优势将是检测错误的异步代码。例如,它可以在单元测试期间捕获任何死锁或异常吞咽。

我不是 100% 肯定是这种情况,所以我真的很想听听社区的意见。

0 投票
1 回答
666 浏览

c# - 等待 TaskCompletionSource从不返回任务

我正在尝试围绕异步发布/订阅系统编写单元测试。在我的单元测试中,我创建一个TaskCompletionSource<int>并在订阅回调中为其分配一个值。在订阅回调中,我取消订阅出版物。下次我发布时,我想验证回调是否从未被击中。

当我这样做时,测试挂在第二个await。我知道这是由于任务永远不会返回而发生的。我不确定如何解决它。我知道我可以轻松地创建一个本地字段,我只需像这样分配值:

不过这感觉不对。这假设我从未在整个堆栈中执行等待操作(当他们是订阅者时我会这样做)。此测试不是安全测试,因为测试可能会在发布完全完成之前完成。这里的意图是我的回调是异步的,并且发布是非阻塞的后台进程。

在这种情况下如何处理 CompletionSource?

0 投票
1 回答
633 浏览

c# - IO Async 方法中的 TaskCompletionSource 使用

ExecuteNonQueryAsync()方法的实现System.Data.SqlClient.SqlCommand如下:

我将其总结为:

  1. 创造TaskCompletionSource<int> source = new TaskCompletionSource<int>();
  2. Task<int>.Factory.FromAsync使用 APM "Begin/End" API创建一个新任务
  3. source.SetResult()任务完成时调用。
  4. 返回source.Task

在这里使用有什么意义,TaskCompletionSource为什么不直接返回由创建的任务Task<int>.Factory.FromAsync()?此任务还包装了结果和异常(如果有)。

在 C# in a Nutshell book 的Asynchronous Programming and Continuations部分中,它指出:

在编写延迟时,我们使用了 TaskCompletionSource,这是实现“底层”I/O 绑定异步方法的标准方法。

对于计算绑定方法,我们使用 Task.Run 来启动线程绑定并发。只需将任务返回给调用者,我们就创建了一个异步方法。

为什么计算绑定的方法可以使用 实现Task.Run(),而不是 I/O 绑定的方法?

0 投票
1 回答
2958 浏览

c# - 如何使用 TaskCompletionSource.SetException 保留等待行为?

(这是对这个问题的一次新尝试,现在更好地证明了这个问题。)

假设我们有一个错误的任务 ( var faultedTask = Task.Run(() => { throw new Exception("test"); });) 并且我们等待它。await将解包AggregateException并抛出底层异常。它会抛出faultedTask.Exception.InnerExceptions.First().

根据源代码,ThrowForNonSuccess它将通过执行任何存储来做到这一点,ExceptionDispatchInfo大概是为了保留漂亮的堆栈跟踪。AggregateException如果没有,它不会解包ExceptionDispatchInfo

仅这一事实就让我感到惊讶,因为文档指出总是抛出第一个异常:https://msdn.microsoft.com/en-us/library/hh156528.aspx?f=255&MSPPError=-2147217396事实证明await可以AggregateException但是,throw没有记录在案的行为。

当我们要创建代理任务并将其设置为异常时,这会成为一个问题:

这会抛出AggregateExceptionawait faultedTask;会抛出测试异常。

如何创建一个我可以随意完成的代理任务,并反映原始任务的异常行为?

原来的行为是:

  1. await将抛出第一个内部异常。
  2. 所有例外情况仍可通过Task.Exception.InnerExceptions. (这个问题的早期版本省略了这个要求。)

这是一个总结发现的测试:

这个问题的动机是我正在尝试构建一个函数,它将一个任务的结果复制到TaskCompletionSource. 这是编写任务组合函数时经常使用的辅助函数。API 客户端无法检测到原始任务和代理任务之间的差异,这一点很重要。

0 投票
0 回答
155 浏览

c# - 我是否需要观察由 TaskCompletionSource 创建的任务的异常属性?

假设我有一个 TaskCompletionSource,我通过 SetException(Exception) 显式设置了它的异常。我是否仍然需要访问其任务的 Exception 属性以避免

“等待任务或访问其异常属性未观察到任务的异常。因此,终结器线程重新抛出未观察到的异常。”

信息?

具体例子:

我是否需要继续()任务以避免在终结器线程上重新抛出异常,还是我很好?

0 投票
1 回答
442 浏览

xamarin - 取消 taskcompletionsource,它从具有超时 xamarin 表单的 API 调用 void 方法

我有这个非异步任务>,它只是请求:

是的,我知道,没什么特别的,只是这个

clientMobile.FindItemsAsync(SetSearchParam(searchString, 100))

是对 void 方法的调用,该方法又调用另一个 void 方法,该方法设置一些参数,然后调用异步方法,该方法本身调用异步方法,该方法执行异步操作以返回项目列表。

问题是,我无法控制上述任务范围之外的任何事情,因为我刚刚解释的所有内容都是 API 的一部分,我不能在其中触摸,也不能对此发表评论,关于它的工作方式,因为我的政策是让我的工作适应它...... -_-

因此,为了做到这一点,我必须在总共 1 分钟过去后立即终止对 FindItemsAsync 的调用......我尝试将上述时间跨度设置为每个一分钟(第一次工作,现在已经进行了一些更改不去),我试着减少一半的时间,不去......

这是调用此任务的代码:

下面是调用此任务的调用者的代码......(真是一团糟-_-):

目前我正在尝试实现 MVVM 架构......

真的,非常感谢您在这件事上的帮助,这很棒,对于给您带来的所有不便,我深表歉意......

编辑

对不起,因为我没有清楚地解释我的目标;它是:我需要获取访问 API 的项目列表,该 API 只是通过 void 方法 FindItemsAsync 与我通信。我有 60 秒的时间来获取所有这些物品。如果出现问题或超时,我必须取消该过程并通知用户出现问题。

那不会发生。它永远不会取消。要么给我物品,要么永远保持加载,尽管我最努力地尝试......我对任务和大部分东西都是新手,因此我经常遇到问题......

0 投票
2 回答
1169 浏览

c# - C# TaskCompletionSource 不工作

我有一个有趣的问题。我有一个登录方法,它适用于 WCF 服务。

我创建了一个任务完成并等待结果到来。

问题是,如果我调用 2 次登录方法,第二次不会返回任何内容。我放了断点,它进入完成的事件,它调用 trysetresult 但没有返回。

这是我的代码

我这样叫;

例如,如果用户第一次输入了错误的登录信息,在第二次尝试中,什么都不会返回。

PS: _registeredEventList 持有是否已经订阅了事件。如果是,则它不会再次创建。当我删除该部分时,它可以工作。