第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

C#:使用 Parallel.ForEach 和異步操作限制最大并發(fā)操作

C#:使用 Parallel.ForEach 和異步操作限制最大并發(fā)操作

C#
慕碼人8056858 2022-01-16 20:05:06
我正在嘗試使用 asp.net core 2.1 實(shí)現(xiàn)自托管 Web 服務(wù),但遇到了實(shí)現(xiàn)后臺(tái)長(zhǎng)時(shí)間執(zhí)行任務(wù)的問(wèn)題。由于每種ProcessSingle方法(在下面的代碼片段中)的高 CPU 負(fù)載和時(shí)間消耗,我想限制同時(shí)執(zhí)行的任務(wù)的數(shù)量。但是我可以看到所有任務(wù)Parallel.ForEach幾乎立即開(kāi)始,盡管我設(shè)置了MaxDegreeOfParallelism = 3我的代碼是(這是一個(gè)簡(jiǎn)化版本):public static async Task<int> Work(){    var id = await CreateIdInDB() // async create record in DB    // run background task, don't wait when it finishes    Task.Factory.StartNew(async () => {        Parallel.ForEach(            listOfData,            new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = 3 },            async x => await ProcessSingle(x));    });    // return created id immediately    return id;}public static async Task ProcessSingle(MyInputData inputData){    var dbData = await GetDataFromDb(); // get data from DB async using Dapper    // some lasting processing (sync)    await SaveDataToDb(); // async save processed data to DB using Dapper}如果我理解正確,問(wèn)題出async x => await ProcessSingle(x)在 Parallel.ForEach 內(nèi)部,不是嗎?有人可以描述一下,它應(yīng)該如何以正確的方式實(shí)施?更新由于我的問(wèn)題存在某種歧義,因此有必要關(guān)注主要方面:方法分為三部分ProcessSingle:從數(shù)據(jù)庫(kù)異步獲取數(shù)據(jù)進(jìn)行長(zhǎng)時(shí)間高 CPU 負(fù)載的數(shù)學(xué)計(jì)算將結(jié)果保存到數(shù)據(jù)庫(kù)異步問(wèn)題包括兩個(gè)獨(dú)立的:如何降低 CPU 使用率(例如同時(shí)運(yùn)行不超過(guò)三個(gè)數(shù)學(xué)計(jì)算)?如何保持ProcessSingle方法的結(jié)構(gòu) - 由于異步 DB 調(diào)用而使它們保持異步。希望現(xiàn)在會(huì)更清楚。PS 已經(jīng)給出了合適的答案,它可以工作(特別感謝@MatrixTai)。編寫(xiě)此更新是為了進(jìn)行一般說(shuō)明。
查看完整描述

2 回答

?
慕森卡

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊

更新


正如我剛剛注意到您在評(píng)論中提到的那樣,問(wèn)題是由數(shù)學(xué)計(jì)算引起的。


將計(jì)算和更新數(shù)據(jù)庫(kù)的部分分開(kāi)會(huì)更好。


對(duì)于計(jì)算部分,使用Parallel.ForEach()以便優(yōu)化您的工作,您可以控制線程數(shù)。


只有在所有這些任務(wù)完成之后。用于async-await將您的數(shù)據(jù)更新到數(shù)據(jù)庫(kù),無(wú)需SemaphoreSlim我提及。


public static async Task<int> Work()

{

    var id = await CreateIdInDB() // async create record in DB


    // run background task, don't wait when it finishes

    Task.Run(async () => {


        //Calculation Part

        ConcurrentBag<int> data = new ConcurrentBag<int>();

        Parallel.ForEach(

            listOfData,

            new ParallelOptions { CancellationToken = token, MaxDegreeOfParallelism = 3 },

            x => {ConcurrentBag.Add(calculationPart(x))});


        //Update DB part

        int[] data_arr = data.ToArray();

        List<Task> worker = new List<Task>();

        foreach (var i in data_arr)

        {

            worker.Add(DBPart(x));

        }

        await Task.WhenAll(worker);

    });


    // return created id immediately

    return id;

}

當(dāng)你async-await在Parallel.forEach.


首先,閱讀第一個(gè)和第二個(gè)答案的這個(gè)問(wèn)題。將這兩者結(jié)合起來(lái)毫無(wú)意義。


實(shí)際上async-await會(huì)最大限度地利用可用線程,所以簡(jiǎn)單地使用它。


public static async Task<int> Work()

{

    var id = await CreateIdInDB() // async create record in DB


    // run background task, don't wait when it finishes

    Task.Run(async () => {

        List<Task> worker = new List<Task>();

        foreach (var i in listOfData)

        {

            worker.Add(ProcessSingle(x));

        }

        await Task.WhenAll(worker);

    });


    // return created id immediately

    return id;

}

但是還有另一個(gè)問(wèn)題,在這種情況下,這些任務(wù)仍然一起開(kāi)始,消耗你的 CPU 使用率。


因此,為避免這種情況,請(qǐng)使用 SemaphoreSlim


public static async Task<int> Work()

{

    var id = await CreateIdInDB() // async create record in DB


    // run background task, don't wait when it finishes

    Task.Run(async () => {

        List<Task> worker = new List<Task>();

        //To limit the number of Task started.

        var throttler = new SemaphoreSlim(initialCount: 20);

        foreach (var i in listOfData)

        {

            await throttler.WaitAsync();

            worker.Add(Task.Run(async () =>

            {

                await ProcessSingle(x);

                throttler.Release();

            }

            ));

        }

        await Task.WhenAll(worker);

    });


    // return created id immediately

    return id;

}


此外,不要Task.Factory.StartNew()在簡(jiǎn)單Task.Run()就足以完成您想要的工作時(shí)使用,請(qǐng)閱讀 Stephen Cleary 撰寫(xiě)的這篇出色的文章。


查看完整回答
反對(duì) 回復(fù) 2022-01-16
?
牛魔王的故事

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊

如果您更熟悉“傳統(tǒng)”并行處理概念,請(qǐng)像這樣重寫(xiě)您的 ProcessSingle() 方法:


public static void ProcessSingle(MyInputData inputData)

{

    var dbData = GetDataFromDb(); // get data from DB async using Dapper

    // some lasting processing (sync)

    SaveDataToDb(); // async save processed data to DB using Dapper

}

當(dāng)然,您最好也以類似的方式更改 Work() 方法。


查看完整回答
反對(duì) 回復(fù) 2022-01-16
  • 2 回答
  • 0 關(guān)注
  • 1156 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)