0

我正在使用一些 async/await 处理具有大量多线程的 WPF 应用程序。我正在考虑在客户端中使用工作单元模式(具有隐式范围)(让它像 TransactionScope 一样工作),但无法决定在哪里存储上下文。

我考虑过的一些事情:

  • 线程本地人;但这不起作用,因为我们可能会在嵌套的工作单元中切换线程。
  • 静止的; 我相信如果同时执行两个不相关的工作单元,这将失败

在我的服务层(webapi odata)中,我将工作单元附加到 http 上下文以允许跨线程嵌套。有没有人在客户端应用程序中尝试过这样的事情,并且有一种体面的方式来确定嵌套工作单元的范围?

4

1 回答 1

1

工作单元并不一定意味着上下文是隐式的(或范围,就此而言)。我相信明确的 UoW 是很正常的(例如,您的 BO 类型会保留对其“拥有”上下文的引用,这本身就是线程安全的)。也就是说,隐式上下文是可能的async

当您await仅在 ASP.NET 请求上下文中使用时,最好的选择是使用HttpContext.Items. 或者,您可以使用线程安全的静态成员。

当您await仅在 UI 上下文中使用时,您可以使用常规静态成员。

当您使用多线程时,您可以使用线程局部变量。

但是,如果您的任何代码使用多线程 await例如,ConfigureAwait(false)或将asynclambda 传递给Task.Run),那么这些选项都不起作用。

AFAIK,只有一个通用的解决方案,我在我的博客上描述CallContext.LogicalGetDataCallContext.LogicalSetData。逻辑调用上下文将跨线程流动,并且可以在任何async情况下工作。

这种方法有一些限制:

  1. 您必须使用 .NET 4.5 框架。CallContextasync在 .NET 4.5 中实现的,因此如果您的目标是 .NET 4.0 / Phone / Silverlight,这将无法正常工作。
  2. 您应该只存储不可变数据。如果您使用Microsoft.Bcl.Immutable,这会变得容易得多。
于 2013-06-28T20:14:06.530 回答