TaskEx.Yield(TaskScheduler) [英] TaskEx.Yield(TaskScheduler)

查看:38
本文介绍了TaskEx.Yield(TaskScheduler)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上个月我问了以下问题,这导致我学习了TaskEx.Yield:

Last month I asked the following question which resulted in my learning of TaskEx.Yield:

异步方法在第一个之前可以有昂贵的代码吗等待"?

然而,我后来意识到这个方法实际上将所有后续代码提交给环境TaskScheduler.本着真正的 DI 精神,我们的团队已同意尽可能避免使用环境实例,所以我想知道是否可以明确指定要使用的 TaskScheduler?

However, I have since realized that this method actually submits all subsequent code to the ambient TaskScheduler. In true DI spirit, our team has agreed to avoid using ambient instances where possible, so I would like to know if it's possible to explicitly specify a TaskScheduler to use?

像下面这样的东西会很棒:

Something like the following would be great:

public static YieldAwaitable Yield(TaskScheduler taskScheduler)
{
    return new YieldAwaitable(taskScheduler);
}

但是,Async CTP 的当前实现仅提供:

However, the current implementation of Async CTP only offers:

public static YieldAwaitable Yield()
{
    return new YieldAwaitable(SynchronizationContext.Current ?? TaskScheduler.Current);
}

以下是否会提供可接受的有效替代方案?

Would the following provide an acceptably efficient alternative?

await Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, this.TaskScheduler);

推荐答案

本着真正的 DI 精神,我们的团队已同意尽可能避免使用环境实例...

In true DI spirit, our team has agreed to avoid using ambient instances where possible...

异步语言支持基于隐式调度上下文.我认为这里不需要依赖注入.如有必要,任何调用您的 async 方法的方法都可以提供自己的上下文.

The async language support is based around an implicit scheduling context. I don't see the need for dependency injection here. Any method calling your async method may supply its own context if necessary.

你的选择:

await Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, this.TaskScheduler);

不会按预期工作.这会将 noop lambda 排入特定的 TaskScheduler 队列,然后在隐式调度上下文中恢复该方法.

will not work as expected. This will queue a noop lambda to a specific TaskScheduler and then resume the method on the implicit scheduling context.

早期版本的 Async CTP 确实提供了屈服于另一个上下文"的方法,称为 SwitchTo.它被删除,因为它太容易了误用.

An earlier version of the Async CTP did provide a "yield to another context" method, called SwitchTo. It was removed because it's too easy to misuse.

就我个人而言,我认为使用其调用方法提供的隐式调度上下文来保持 async 代码更简洁.

Personally, I think it's cleaner to keep your async code using its implicit scheduling context, which is provided by its calling method.

附言创建和安装您自己的上下文并不(太)困难,例如,用于测试目的.我编写了 AsyncContext 作为单元测试和控制台程序的简单调度上下文.异步 CTP 带有 GeneralThreadAffineContextWindowsFormsContextWpfContext 用于测试.任何这些都可以使用 SynchronizationContext.SetSynchronizationContext 安装.IMO,DI 是矫枉过正.

P.S. It's not (too) difficult to create and install your own context, e.g., for testing purposes. I wrote AsyncContext as a simple scheduling context for unit testing and Console programs. The Async CTP comes with GeneralThreadAffineContext, WindowsFormsContext, and WpfContext for testing. Any of these can be installed using SynchronizationContext.SetSynchronizationContext. IMO, DI is overkill.

这篇关于TaskEx.Yield(TaskScheduler)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆