问题标签 [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.
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.
c# - 包装使用基于事件的异步模式的库,用于 Async/Await
我在整个代码中使用异步/等待模式。但是,有一个 API 使用了基于事件的异步模式。我在 MSDN 和几个 StackOverflow 上阅读过答案,这样做的方法是使用 TaskCompletionSource。
我的代码:
并称为:
或者,为了测试:
该方法总是很快返回,但没有一个事件被触发。
如果我添加 tcs.Task.Await(); 就在 return 语句之前,它可以工作,但这并没有提供我想要的异步行为。
我已经与我在互联网上看到的各种样本进行了比较,但没有发现任何差异。
c# - 如何将同步上下文/任务调度程序替换为 TaskCompletionSource.Task 中的另一个同步上下文/任务调度程序以获取 ConfigureAwait(false)?
假设我创建了一个包含此类方法的库:
我的 lib 的任何用户都可以MyLibraryMethodAsync
这样调用
问题来了——VeryLongRunningMethod
将在taskCompletionSource.SetResult(null)
调用内部执行,因此它将阻塞workerThread
很长一段时间,这是不希望的行为,因为workerThread
它旨在运行一小部分代码(工作项)。
如何将上下文/调度程序替换为返回的任务中的线程池await x.ConfigureAwait(false)
以继续在线程池上,而不是在线程池上workerThread
?
我找到的当前解决方案是
但是,我不喜欢它,因为它会产生开销。可能存在更优雅的解决方案吗?
c# - 模拟异步方法
我们正在使用 MSTest 和 Moq 为异步代码编写单元测试。
所以我们有一些看起来像这样的代码:
或者像这样在具有更新版本 Moq 的项目上
查看 ReturnsAsync 的 Moq 实现:
这两种方法在引擎盖下似乎是相同的。两者都创建一个TaskCompletionSource
,调用SetResult
并返回Task
到目前为止,一切都很好。
但是短期运行的async
方法被优化为同步运行。这似乎意味着TaskCompletionSource
始终是同步的,这似乎也表明上下文处理和任何可能发生的相关问题永远不会发生。
因此,如果我们有一些代码执行了一些async
禁止操作,例如混合和awaits
,那么在单元测试中就不会检测到这些问题。Wait()
Result
创建一个总是产生控制权的扩展方法有什么好处吗?就像是 :
在这种情况下,我们将有一个保证异步执行的方法。
感知到的优势将是检测错误的异步代码。例如,它可以在单元测试期间捕获任何死锁或异常吞咽。
我不是 100% 肯定是这种情况,所以我真的很想听听社区的意见。
c# - 等待 TaskCompletionSource从不返回任务
我正在尝试围绕异步发布/订阅系统编写单元测试。在我的单元测试中,我创建一个TaskCompletionSource<int>
并在订阅回调中为其分配一个值。在订阅回调中,我取消订阅出版物。下次我发布时,我想验证回调是否从未被击中。
当我这样做时,测试挂在第二个await
。我知道这是由于任务永远不会返回而发生的。我不确定如何解决它。我知道我可以轻松地创建一个本地字段,我只需像这样分配值:
不过这感觉不对。这假设我从未在整个堆栈中执行等待操作(当他们是订阅者时我会这样做)。此测试不是安全测试,因为测试可能会在发布完全完成之前完成。这里的意图是我的回调是异步的,并且发布是非阻塞的后台进程。
在这种情况下如何处理 CompletionSource?
c# - IO Async 方法中的 TaskCompletionSource 使用
ExecuteNonQueryAsync()
方法的实现System.Data.SqlClient.SqlCommand
如下:
我将其总结为:
- 创造
TaskCompletionSource<int> source = new TaskCompletionSource<int>();
Task<int>.Factory.FromAsync
使用 APM "Begin/End" API创建一个新任务source.SetResult()
任务完成时调用。- 返回
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 绑定的方法?
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没有记录在案的行为。
当我们要创建代理任务并将其设置为异常时,这会成为一个问题:
这会抛出AggregateException
而await faultedTask;
会抛出测试异常。
如何创建一个我可以随意完成的代理任务,并反映原始任务的异常行为?
原来的行为是:
await
将抛出第一个内部异常。- 所有例外情况仍可通过
Task.Exception.InnerExceptions
. (这个问题的早期版本省略了这个要求。)
这是一个总结发现的测试:
这个问题的动机是我正在尝试构建一个函数,它将一个任务的结果复制到TaskCompletionSource
. 这是编写任务组合函数时经常使用的辅助函数。API 客户端无法检测到原始任务和代理任务之间的差异,这一点很重要。
c# - 我是否需要观察由 TaskCompletionSource 创建的任务的异常属性?
假设我有一个 TaskCompletionSource,我通过 SetException(Exception) 显式设置了它的异常。我是否仍然需要访问其任务的 Exception 属性以避免
“等待任务或访问其异常属性未观察到任务的异常。因此,终结器线程重新抛出未观察到的异常。”
信息?
具体例子:
我是否需要继续()任务以避免在终结器线程上重新抛出异常,还是我很好?
xamarin - 取消 taskcompletionsource,它从具有超时 xamarin 表单的 API 调用 void 方法
我有这个非异步任务>,它只是请求:
是的,我知道,没什么特别的,只是这个
clientMobile.FindItemsAsync(SetSearchParam(searchString, 100))
是对 void 方法的调用,该方法又调用另一个 void 方法,该方法设置一些参数,然后调用异步方法,该方法本身调用异步方法,该方法执行异步操作以返回项目列表。
问题是,我无法控制上述任务范围之外的任何事情,因为我刚刚解释的所有内容都是 API 的一部分,我不能在其中触摸,也不能对此发表评论,关于它的工作方式,因为我的政策是让我的工作适应它...... -_-
因此,为了做到这一点,我必须在总共 1 分钟过去后立即终止对 FindItemsAsync 的调用......我尝试将上述时间跨度设置为每个一分钟(第一次工作,现在已经进行了一些更改不去),我试着减少一半的时间,不去......
这是调用此任务的代码:
下面是调用此任务的调用者的代码......(真是一团糟-_-):
目前我正在尝试实现 MVVM 架构......
真的,非常感谢您在这件事上的帮助,这很棒,对于给您带来的所有不便,我深表歉意......
编辑
对不起,因为我没有清楚地解释我的目标;它是:我需要获取访问 API 的项目列表,该 API 只是通过 void 方法 FindItemsAsync 与我通信。我有 60 秒的时间来获取所有这些物品。如果出现问题或超时,我必须取消该过程并通知用户出现问题。
那不会发生。它永远不会取消。要么给我物品,要么永远保持加载,尽管我最努力地尝试......我对任务和大部分东西都是新手,因此我经常遇到问题......
c# - C# TaskCompletionSource 不工作
我有一个有趣的问题。我有一个登录方法,它适用于 WCF 服务。
我创建了一个任务完成并等待结果到来。
问题是,如果我调用 2 次登录方法,第二次不会返回任何内容。我放了断点,它进入完成的事件,它调用 trysetresult 但没有返回。
这是我的代码
我这样叫;
例如,如果用户第一次输入了错误的登录信息,在第二次尝试中,什么都不会返回。
PS: _registeredEventList 持有是否已经订阅了事件。如果是,则它不会再次创建。当我删除该部分时,它可以工作。