gpt4 book ai didi

c# - 在 PCL 和 Windows Phone 应用程序中实现异步作用域

转载 作者:太空狗 更新时间:2023-10-29 21:49:21 25 4
gpt4 key购买 nike

出于某种奇怪的原因,System.Runtime.Remoting.Messaging.CallContextAsyncLocal类只能使用完整的 CLR。这使得在使用可移植类库或 Windows Phone 应用程序时很难进行异步范围界定,特别是因为 Windows Phone API 正变得仅异步;所以我们真的没有不使用 async/await 的选项。

这实际上意味着在 WPF 或 WinForms 中,我们可以这样编写方法:

private async void button_Click(object sender, EventArgs e)
{
CallContext.LogicalSetData("x", new object());
await Something();
var context = CallContext.LogicalGetData("x");
}

在 WPF 和 WinForms 中,框架确保每次单击同一个按钮都获得自己的上下文,并且可以独立运行。使用 ThreadLocal<T> 很难达到同样的效果和 [ThreadStatic]因为每次点击都会在 UI 线程上执行。

我的问题是,我们如何在 Windows Phone、Store 和其他不支持 CallContext 的应用程序类型中解决这个问题?和 AsyncLocal<T> ?

一些背景信息:

我们经常希望(业务)逻辑在某种上下文中运行。此上下文可以包含业务逻辑可以在整个操作过程中使用的信息。在服务器环境中,这真的很容易想象,因为您需要在数据库事务中运行请求,需要访问当前用户、租户 ID 等。但即使在客户端应用程序中,操作也可能需要访问上下文信息,例如当前正在运行的操作的相关 ID 或日志记录的上下文。在此类操作(如点击事件)期间,我们可能需要解析其他服务(来 self 们的 Composition Root )。为了操作成功,我们可能需要在整个客户端操作中重复使用相同的组件,这意味着我们的组合根需要知道它正在运行的上下文。

虽然所有这些信息都可以使用服务公共(public) API 的方法调用在整个系统中传递,但这不仅会迫使我们用实现细节污染我们应用程序中服务的 API,还会导致严重的维护问题,因为我们必须在整个系统中传递所有这些信息,并且对我们的一个组件进行简单的内部更改会通过所有方法调用向上传播调用堆栈。当涉及到我们的组合根时,我们绝对不想通过应用程序传递我们的 DI 库的某些缓存/作用域对象,因为这会将我们的业务逻辑紧密地耦合到外部库。显然,我们也不想传递某种 service locator .

因此,使用 CallContext 之类的东西来实现范围界定或 AsyncLocal<T>在客户端应用程序中非常重要。

最佳答案

抱歉,今天没有简单的解决方案。当 Windows Phone(最终)成为“手机上的 Windows 10”(即 AsyncLocal<T> )时,这将成为可能。但是现在……

最简单的方法是显式(作为参数)或隐式(作为 this 上的成员变量)传递上下文。

也可以通过自定义等待者实现此功能的有限版本。但除了非常复杂之外,该解决方案还需要您修改每个 await在您的整个应用程序中(或使用编译后 IL 重写来实现相同的效果)。

关于c# - 在 PCL 和 Windows Phone 应用程序中实现异步作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33843187/

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