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

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

问题描述

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

<一个href="http://stackoverflow.com/questions/8449111/can-async-methods-have-expensive-$c$c-before-the-first-await">Can异步方法有昂贵的code之前的第一个等待?

不过,因为我已经意识到,这种方法实际上提出所有后续code的环境的TaskScheduler 。在真正的DI精神,我们的团队已经同意,以避免使用环境情况下可能的,所以我想知道是否有可能显式地指定一个的TaskScheduler 使用?

类似以下内容将是巨大的:

 公共静态YieldAwaitable产量(的TaskScheduler的TaskScheduler)
{
    返回新YieldAwaitable(的TaskScheduler);
}
 

不过,异步CTP目前实施不仅提供:

 公共静态YieldAwaitable收益率()
{
    返回新YieldAwaitable(SynchronizationContext.Current?TaskScheduler.Current);
}
 

请问下面提供了一个可以接受的有效的替代?

 等待Task.Factory.StartNew(()=&GT; {},CancellationToken.None,TaskCreationOptions.None,this.TaskScheduler);
 

解决方案
  

在真正的DI精神,我们的团队已经同意,以避免使用环境情况下可能的...

异步语言支持是基于一个隐含的调度环境。我不认为有必要依赖注入这里。任何方法调用你的异步方法,如果需要,可以提供自己的内容。

您选择:

 等待Task.Factory.StartNew(()=&GT; {},CancellationToken.None,TaskCreationOptions.None,this.TaskScheduler);
 

如预期将无法正常工作。这将排队一个空操作,拉姆达到一个特定的的TaskScheduler ,然后继续在隐调度范围内的方法。

异步CTP的早期版本确实提供了收益率到另一个环境的方法,叫做 SwitchTo 。它<一个href="http://social.msdn.microsoft.com/Forums/en-US/async/thread/642ffef6-d3ce-4010-978d-bc5d8b65c00f"相对=nofollow>辗转,因为它太容易误操作。

就个人而言,我认为这是更清洁,让您的异步 code。使用其隐含的调度方面,这是由它的调用方法提供的。

P.S。这不是(太),难以创建和安装自己的情况下,例如,用于测试目的。我写 AsyncContext 作为一个简单的调度方面进行单元测试和控制台程序。在异步CTP带有 GeneralThreadAffineContext WindowsFormsContext WpfContext 进行测试。所有这些都可以通过安装 SynchronizationContext.SetSynchronizationContext 。国际海事组织,DI是矫枉过正。

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

Can async methods have expensive code before the first 'await'?

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);
}

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);

解决方案

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

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.

Your alternative:

await Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, this.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.

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.

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

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天全站免登陆