我什么时候可以使用Task.Yield()?
我使用asynchronous/等待和Task
很多,但从来没有使用Task.Yield()
,说实话,即使所有的解释,我不明白为什么我会需要这种方法。
有人可以给出一个很好的例子, Yield()
是必需的吗?
当你使用async
/ await
,不能保证你在await FooAsync()
时调用的方法实际上是asynchronous运行的。 内部实现可以使用完全同步的path自由返回。
如果你正在制作一个关键的API,它不会阻塞,并且你可以asynchronous地运行一些代码,并且有可能被调用的方法将同步运行(有效地阻塞),使用await Task.Yield()
会强制你的方法是asynchronous的,并在那一刻返回控制权。 剩下的代码将会在当前的上下文中执行(此时它仍然可以同步运行)。
如果你制作一个需要一些“长时间运行”初始化的asynchronous方法,这也是有用的,即:
private async void button_Click(object sender, EventArgs e) { await Task.Yield(); // Make us async right away var data = ExecuteFooOnUIThread(); // This will run on the UI thread at some point later await UseDataAsync(data); }
没有Task.Yield()
调用,该方法将一直同步执行,直到第一个调用await
。
在内部,如果SynchronizationContext.Current
为null
,则await Task.Yield()
只是在当前同步上下文或随机池线程上对继续进行排队。
它是自定义的服务器有效地实现 。 产生相同效果的效率较低的代码可能如此简单:
var tcs = new TaskCompletionSource<bool>(); var sc = SynchronizationContext.Current; if (sc != null) sc.Post(_ => tcs.SetResult(true), null); else ThreadPool.QueueUserWorkItem(_ => tcs.SetResult(true)); await tcs.Task;
Task.Yield()
可以用作一些奇怪的执行stream改变的捷径。 例如:
async Task DoDialogAsync() { var dialog = new Form(); Func<Task> showAsync = async () => { await Task.Yield(); dialog.ShowDialog(); } var dialogTask = showAsync(); await Task.Yield(); // we're on the dialog's nested message loop MessageBox.Show("The dialog is visible, click OK to close"); dialog.Close(); await dialogTask; // we're back to the main message loop }
这就是说,我不能想到Task.Yield()
不能被Task.Factory.StartNew
replace为适当的任务调度程序。
也可以看看:
-
“等待Task.Yield()”及其替代品
-
Task.Yield – 真正的用法?
我有一个基类,它有一个主要的方法:
public async Task SendAsync (message);
然后,我决定在以后的日子,我想审核发送的消息在基类的更高级的变体,我添加了两个基本的方法:
protected virtual async Task OnBeforeSend(message); protected virtual async Task OnAfterSend(message);
在我的类的专门版本中,我将实现添加到发送消息之前和之后的方法中,但不需要在发送方法之前和之后添加自定义到我的基类实现。 我要求我的基地实施也是一个具体的types,因为它正在其他地方使用。
为了保持编译器的快乐,我需要提供一个任务结果给基础(空)的实现,我为此使用了Task.Yield()方法。 因此,在我的基类实现中,我有这样的:
protected virtual async Task OnBeforeSend(IEmailMessage mailMessage) { await Task.Yield(); }
这似乎对我很好,我看不出这是错的。
- 不能隐式地将types“string”转换为“System.Threading.Tasks.Task <string>”
- 你如何在C#中创build一个asynchronous方法?
- 如何使用LINQasynchronous地等待任务列表?
- 使用asynchronous/等待多个任务
- 我将如何同步运行asynchronous任务<T>方法?
- 为什么在等待后HttpContext.Current为空?
- 任何区别“await Task.Run(); 返回;“和”返回Task.Run()“?
- 是否有可能等待一个事件,而不是另一个asynchronous方法?
- HttpClient.GetAsync与networking凭据