日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

出让执行权:Task.Yield, Dispatcher.Yield

發(fā)布時(shí)間:2023/12/4 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 出让执行权:Task.Yield, Dispatcher.Yield 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一個(gè)耗時(shí)的任務(wù),可以通過(guò) Task.Yield 或者 Dispatcher.Yield 來(lái)中斷以便分割成多個(gè)小的任務(wù)片段執(zhí)行。

Yield?這個(gè)詞很有意思,叫做“屈服”“放棄”“讓步”,字面意義上是讓出當(dāng)前任務(wù)的執(zhí)行權(quán),轉(zhuǎn)而讓其他任務(wù)可以插入執(zhí)行。Task、Dispatcher、Thread?都有?Yield()?方法,看起來(lái)都可以讓出當(dāng)前任務(wù)的執(zhí)行權(quán)。



本文內(nèi)容
  • Dispatcher.Yield

    • 需要注意

  • Task.Yield


如果在閱讀中發(fā)現(xiàn)對(duì)本文涉及到的一些概念不太明白,可以閱讀:

  • 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)

  • 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分)


如果一個(gè)方法的實(shí)現(xiàn)比較耗時(shí),為了不影響 UI 的響應(yīng),你會(huì)選擇用什么方法呢?我之前介紹過(guò)的?Invoke 和 InvokeAsync?可以解決,將后續(xù)耗時(shí)的任務(wù)分割成一個(gè)個(gè)小的片段以低于用戶輸入和渲染的優(yōu)先級(jí)執(zhí)行。

Dispatcher.Yield?也可以,其行為更加類似于?Dispatcher.InvokeAsync(即采用?Dispatcher?調(diào)度的方式,事實(shí)上后面會(huì)說(shuō)到其實(shí)就是調(diào)用了?InvokeAsync),而非?Dispatcher.Invoke(即采用?PushFrame?新開消息循環(huán)的方式)。

使用時(shí)需要?await:

foreach(var item in collection)
{
DoWorkWhichWillTakeHalfASecond();
await Dispatcher.Yield();
}

這樣,這個(gè)?foreach?將在每遍歷到一個(gè)集合項(xiàng)的時(shí)候中斷一次,讓 UI 能夠響應(yīng)用戶的交互輸入和渲染。

Yield?方法可以傳入一個(gè)優(yōu)先級(jí)參數(shù),指示繼續(xù)執(zhí)行后續(xù)任務(wù)的優(yōu)先級(jí)。默認(rèn)是?DispatcherPriority.Background,低于用戶輸入?DispatcherPriority.Input、 UI 邏輯?DispatcherPriority.Loaded?和渲染?DispatcherPriority.Render。

Dispatcher.Yield?是如何做到出讓執(zhí)行權(quán)的呢?

查看源碼,發(fā)現(xiàn)?DispatcherYield?的返回值是?DispatcherPriorityAwaiter,而它的?OnCompleted?方法是這樣的:

public void OnCompleted(Action continuation)
{
if(_dispatcher == null)
throw new InvalidOperationException(SR.Get(SRID.DispatcherPriorityAwaiterInvalid));
_dispatcher.InvokeAsync(continuation, _priority);
}

所以,其實(shí)真的就是?InvokeAsync。如果希望了解為何是?OnCompleted?方法,可以閱讀?【C#】【多線程】【05-使用C#6.0】08-自定義awaitable類型 - L.M。

Dispatcher.Yield?是?Dispatcher?類型的靜態(tài)方法,而不是像?InvokeAsync一樣是實(shí)例方法。不過(guò) C# 有一個(gè)神奇的特性——靜態(tài)方法和實(shí)例方法可以在同一上下文中調(diào)用,而不用擔(dān)心產(chǎn)生歧義。

例如:

using System.Windows.Threading;

class Demo : DispatcherObject
{
void Test()
{
// 調(diào)用靜態(tài)方法 Yield。
await Dispatcher.Yield();
// 調(diào)用實(shí)例方法 InvokeAsync。
await Dispatcher.InvokeAsync(() => { });
}
}

注意需要引用命名空間?System.Windows.Threading。


拿前面?Dispatcher.Yield?的例子,我們換成?Task.Yield:

foreach(var item in collection)
{
DoWorkWhichWillTakeHalfASecond();
await Task.Yield();
}

效果與?Dispatcher.Yield(DispatcherPriority.Normal)?是一樣的。因?yàn)?Task?調(diào)度回到線程上下文靠的是?SynchronizationContext,WPF UI 線程的?SynchronizationContext?被設(shè)置為了?DispatcherSynchronizationContext,使用?Dispatcher?調(diào)度;而?DispatcherSynchronizationContext?構(gòu)造時(shí)傳入的優(yōu)先級(jí)默認(rèn)是?Normal,WPF 并沒有特殊傳入一個(gè)別的值,所以 WPF UI 線程上使用?Task.Yield()?出讓執(zhí)行權(quán)后,恢復(fù)時(shí)使用的是?Normal?優(yōu)先級(jí),相當(dāng)于 Dispatcher.Yield(DispatcherPriority.Normal)。

希望了解?Dispatcher?和?SynchronizationContext?的區(qū)別可以閱讀?c# - Difference between Synchronization Context and Dispatcher - Stack Overflow。

DispatcherSynchronizationContext?執(zhí)行?await?后續(xù)任務(wù)的上下文代碼:

/// <summary>
/// Asynchronously invoke the callback in the SynchronizationContext.
/// </summary>
public override void Post(SendOrPostCallback d, Object state)
{
// Call BeginInvoke with the cached priority. Note that BeginInvoke
// preserves the behavior of passing exceptions to
// Dispatcher.UnhandledException unlike InvokeAsync. This is
// desireable because there is no way to await the call to Post, so
// exceptions are hard to observe.
_dispatcher.BeginInvoke(_priority, d, state);
}

既然是?Normal?優(yōu)先級(jí),那么在 UI 線程上的效果自然不如?Dispatcher.Yield。但是,Task.Yield?適用于任何線程,因?yàn)?SynchronizationContext?本身是與?Dispatcher?無(wú)關(guān)的,適用于任何線程。這樣,于如果一個(gè)?Task?內(nèi)部的任務(wù)太耗時(shí),用?Task.Yield?則可以做到將此任務(wù)分成很多個(gè)片段執(zhí)行。

如果覺得?Task.Yield()?的用途難以理解,可以參考?dudu?的博客?終于明白了 C# 中 Task.Yield 的用途 - dudu - 博客園。


參考資料

  • c# - Task.Yield - real usages? - Stack Overflow

  • Task.Yield Method (System.Threading.Tasks)

  • c# - Difference between Synchronization Context and Dispatcher - Stack Overflow

原文地址:https://walterlv.com/post/yield-in-task-dispatcher.html

.NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總?http://www.csharpkit.com?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的出让执行权:Task.Yield, Dispatcher.Yield的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品国产亚洲AV无码麻豆 | 在线观看特色大片免费网站 | 8x8x永久免费视频 | 97人妻一区二区精品视频 | 国产一级自拍视频 | 中文日韩av | 欧美乱妇狂野欧美在线视频 | 九色91丨porny丨丝袜 | 一级淫片免费 | 日韩中文字幕视频在线 | 欧美视频在线不卡 | 五月天婷婷丁香花 | 中文字幕亚洲不卡 | 好吊视频一区 | 国产伦精品一区二区. | 色综合久久精品亚洲国产 | 国产片自拍 | 精品成在人线av无码免费看 | 亚洲 激情 | 麻豆 美女 丝袜 人妻 中文 | av网站免费在线看 | 国产美女福利视频 | 黄色在线视频网站 | 国产成人一区二区三区小说 | 免费看美女被靠到爽的视频 | 欧洲免费av| 爱情岛论坛永久入址测速 | 91久久在线 | 日本美女高潮 | 亚洲一区二区三区四区在线观看 | 亚洲国产精品无码久久久 | 黄色亚洲网站 | 久久资源av | 神马午夜888 | 欧美贵妇videos办公室 | 精品日日夜夜 | 黑人添美女bbb添高潮了 | 日本一区不卡视频 | 99av国产精品欲麻豆 | 国产中文字幕在线视频 | 亚洲中文字幕无码不卡电影 | 久久亚洲AV成人无码国产人妖 | 亚洲宅男天堂 | 国产午夜精品在线观看 | 亚洲黄色免费网站 | 国产三级漂亮女教师 | 精精国产xxxx视频在线播放 | 破处视频在线观看 | 久久精品免费网站 | 欧美激情婷婷 | 国产jk精品白丝av在线观看 | 日本熟妇色xxxxx日本免费看 | 亚洲精品一区二区三区影院忠贞 | 天天干夜夜爽 | 黄色一级生活片 | 国产在线www | 经典av在线| 精品人妻互换一区二区三区 | 午夜精品久久久久久毛片 | 欧美精品在线免费观看 | 蜜桃av噜噜| 精品人伦一区二区三区蜜桃免费 | 一级特黄aa | 成人精品一区二区三区中文字幕 | 成人精品视频在线播放 | 欧美区在线观看 | 亚洲一区二区三区成人 | 免费在线精品视频 | 中文字幕精品一区二区精品 | 国产喷水福利在线视频 | 国产黄色激情视频 | av大全在线观看 | 色偷偷av一区二区三区 | 99热思思 | 日韩中文在线一区 | 久久精品视频一区二区 | 国产suv精品一区二区60 | 中文字幕在线视频不卡 | 亚洲激情视频一区 | 国产无码精品视频 | 在线视频三区 | 午夜不卡福利视频 | 免费久久精品视频 | www.四虎. | 丝袜 中出 制服 人妻 美腿 | 日韩欧美视频一区二区 | 伊人久久大香线蕉成人综合网 | aa成人 | 激情亚洲色图 | 国产精九九网站漫画 | 日本特级淫片 | av十大美巨乳 | 亚洲精华液一区二区 | 国产女女 | 亚洲精品日产精品乱码不卡 | 日韩女优在线播放 | 一区二区三区中文字幕 | 波多野结衣高清电影 | 色婷婷av一区二区三区麻豆综合 |