【发布时间】:2015-10-04 04:18:42
【问题描述】:
我对 TaskCompletionSource 有一个不寻常的问题,这让我很困惑。一旦我调用 TrySetResult,我就有一个 TaskCompletionSource 等待任务完成。我在代码中的三个地方调用它:从 WCF 线程立即返回一个值到 APM WCF BeginXXX EndXXX;从另一个 WCF 线程立即返回到 APM;最后来自 NServiceBus 处理程序线程。
我从 MS-PL 提供的无处不在的 ToAPM 开始。 http://blogs.msdn.com/b/pfxteam/archive/2011/06/27/using-tasks-to-implement-the-apm-pattern.aspx
我注意到两个基于 WCF 的线程 100% 的时间都在工作。在 100 小时的艰苦测试和大量单元测试中,我从未遇到过将已完成任务返回到 AsyncCallback 的失败。
从 MS 提供的 ToAPM 代码中,该代码在已完成的任务上使用 ContinueWith 来调用已启用计划的任务中的 AsyncCallback。
我没有解决的问题是 NServiceBus 线程在 TaskCompletionSource 对象上调用 TrySetResult。我发现中断时间,在未定义的时间段内,呼叫根本失败。我在代码中为调用和 ContinueWith 代码设置断点。我总是在 TrySetResult 上获得断点,但有时仅在 ContinueWith 代码内的代码上。
以下信息希望能对此事有所帮助。
我使用具有超时功能的 CancellationTokenSource 并设置结果以调用 TaskCompletionSource obj 上的 TrySetResult。当上述调用无法将任务移至完成时,将触发超时代码。此超时代码从未起作用。它的成功率是 100%。
有趣的是,在从 NServiceBus 线程调用 TrySetResult 的同一代码中,当它工作时,它可以像调用 TaskCompletionSource obj 上的 TrySetResult 一样轻松调用取消对象的 Cancel。
当一个失败时,他们都会失败。
然后在不分青红皂白的一段时间后再次工作。
这是生产和 QA 环境中的 WCF 服务器,每个服务器都显示相同的结果。
最奇怪的是,对于一个 WCF 连接,NServiceBus 线程同时成功而另一个失败。然后有时两者都工作,然后都失败了。再次,所有在同一时间。
我尝试了很多方法来解决这个问题,但无济于事:
- 我将对 TrySetResult 的调用封装在 TaskCompletionSource + ContinueWith 中 -- 失败
- 我将调用封装在 Task.Factory.StartNew 中 -- 失败
- 我直接调用它——失败
我真的不知道还能尝试什么。
我进行了检查以确保 TaskCompletionSource obj 未完成,并且在中断期间未完成。 我进行了检查以确保 CancellationTokenSource 对象在中断期间没有被取消或有取消挂起,但它没有。
我检查了调试器中的对象,它们看起来不错。
他们只是不工作有时。
NserviceBus 线程中是否存在不一致有时会阻止调用工作? 我可以尝试一些线程编组吗?
我到处搜索,但没有看到有人提到这个问题。它是独一无二的吗?
我完全感到困惑,需要一些想法。
【问题讨论】:
-
您需要发布所有相关代码。
标签: multithreading wcf asynchronous task-parallel-library nservicebus