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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.Net Framework 4.0 中利用Task实现并行处理、串并行混合处理

發(fā)布時(shí)間:2025/7/14 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Framework 4.0 中利用Task实现并行处理、串并行混合处理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

??? 我們常常會(huì)遇到需要利用并行處理,盡量發(fā)揮多核或多CPU的潛能,提高程序運(yùn)行效率的場(chǎng)景。在.NET環(huán)境下,常用的做法是使用Thread,多線程方式進(jìn)行并行處理。但在.Net4.0中,微軟提供一種新的概念——Task(任務(wù)),換句話說(shuō),并行處理由“多線程”進(jìn)化為了“多任務(wù)”的方式。

?

一、利用Task實(shí)現(xiàn)多任務(wù)處理

測(cè)試1:

以下為測(cè)試過(guò)程,模擬多次調(diào)用一耗時(shí)方法,分別使用串行、多線程方式、多任務(wù)方式:

1、建立一虛擬耗時(shí)的方法

/// <summary>
/// 模擬執(zhí)行耗時(shí)的方法
/// </summary>
public static void TestLongTimeMethod()
{
Console.WriteLine("method start:" + System.DateTime.Now.ToString());
System.Threading.Thread.Sleep(5000);
Console.WriteLine("method end:" + System.DateTime.Now.ToString());
}

?

2、傳統(tǒng)串行調(diào)用方式、多線程調(diào)用、多任務(wù)調(diào)用

#region 傳統(tǒng)串行方式
/// <summary>
/// 傳統(tǒng)串行方式
/// </summary>
public static void lineMethod()
{
TestLongTimeMethod();
TestLongTimeMethod();
TestLongTimeMethod();
}
#endregion #region 多線程方式
/// <summary>
/// 多線程方式
/// </summary>
public static void threadMethod()
{
var thread1 = new Thread(() => TestLongTimeMethod());
var thread2 = new Thread(() => TestLongTimeMethod());
thread1.Start();
thread2.Start();
TestLongTimeMethod();
thread1.Join();
thread2.Join();
}
#endregion #region 多任務(wù)方式
/// <summary>
/// 多任務(wù)方式——線程池中,委托給CPU,全部執(zhí)行完后再跳出線程池
/// </summary>
public static void taskMethod()
{
// 方式1:使用Parallel.Invoke,可同時(shí)并行多個(gè)任務(wù),任務(wù)調(diào)用的方法可以不同
//Parallel.Invoke(
// () => TestLongTimeMethod(),
// () => TestLongTimeMethod(),
// () => TestLongTimeMethod()
//);

// 方式2:使用Parallel.For,可設(shè)定并行多個(gè)任務(wù),任務(wù)調(diào)用的方法相同
int times = 3;
Parallel.For(
0,
times,
i => TestLongTimeMethod()
);
}
#endregion

3、模擬執(zhí)行過(guò)程,統(tǒng)計(jì)過(guò)程用時(shí)

static void Main(string[] args)
{
int maxTimes = 1;
DateTime ds = new DateTime();
DateTime de = new DateTime();
DateTime ds1 = new DateTime();
DateTime de1 = new DateTime();
DateTime ds2 = new DateTime();
DateTime de2 = new DateTime();

#region lineMethod 串行

Console.WriteLine("**************【串 行】**************");
ds = DateTime.Now;
Console.WriteLine("**************[StartTime:" + ds.ToString() + "]**************");
for (int intLoop = 0; intLoop < maxTimes; intLoop++)
{
Console.WriteLine("**************[" + (intLoop + 1).ToString() + "]**************");
lineMethod();
}
de = DateTime.Now;
Console.WriteLine("**************[EndTime:" + de.ToString() + "]**************");
System.Threading.Thread.Sleep(500);

#endregion

#region threadMethod 多線程

Console.WriteLine("**************【多線程】**************");
ds1 = DateTime.Now;
Console.WriteLine("**************[StartTime:" + ds1.ToString() + "]**************");
for (int intLoop = 0; intLoop < maxTimes; intLoop++)
{
Console.WriteLine("**************[" + (intLoop + 1).ToString() + "]**************");
threadMethod();
}
de1 = DateTime.Now;
Console.WriteLine("**************[EndTime:" + de1.ToString() + "]**************");
System.Threading.Thread.Sleep(500);

#endregion

#region taskMethod 多任務(wù)

Console.WriteLine("**************【多任務(wù)】**************");
ds2 = DateTime.Now;
Console.WriteLine("**************[StartTime:" + ds2.ToString() + "]**************");
for (int intLoop = 0; intLoop < maxTimes; intLoop++)
{
Console.WriteLine("**************[" + (intLoop + 1).ToString() + "]**************");
taskMethod();
}
de2 = DateTime.Now;
Console.WriteLine("**************[EndTime:" + de2.ToString() + "]**************");
System.Threading.Thread.Sleep(500);

#endregion

Console.WriteLine("lineMethod 【串 行】 : " + (de - ds).TotalMilliseconds.ToString());
Console.WriteLine("threadMethod【多線程】 : " + (de1 - ds1).TotalMilliseconds.ToString());
Console.WriteLine("taskMethod 【多任務(wù)】 : " + (de2 - ds2).TotalMilliseconds.ToString());


Console.ReadLine();
}

4、執(zhí)行結(jié)果截圖

?

結(jié)論:從結(jié)果可以看出多線程或多任務(wù)的性能明顯高于串行方式。多線程或多任務(wù)執(zhí)行效率區(qū)別不大,.NET框架底層實(shí)現(xiàn)可能大致相同。但多任務(wù)的代碼寫法更為簡(jiǎn)潔,也更為靈活。

?

二、利用Task實(shí)現(xiàn)并行、串行的執(zhí)行順序定義

測(cè)試2::

1、假定A、B、C、D、E 多任務(wù)的執(zhí)行順序?yàn)?#xff1a;A、B 執(zhí)行后,執(zhí)行C,A?執(zhí)行后,執(zhí)行 D, B?執(zhí)行后,執(zhí)行 E
執(zhí)行時(shí)的測(cè)試方法如下(即執(zhí)行時(shí)顯示執(zhí)行的名稱,并按傳入的時(shí)間參數(shù),決定進(jìn)程休眠的時(shí)間):

public class TestAction
{
private int _p;
private string _actionName;

public TestAction(string actionName, int p)
{
_actionName = actionName;
_p = p;
}

public void Do()
{
Console.WriteLine(System.DateTime.Now.ToString() + " | 開(kāi)始執(zhí)行" + _actionName);
Thread.Sleep(new TimeSpan(0, 0, _p));
Console.WriteLine(System.DateTime.Now.ToString() + " | 執(zhí)行完畢" + _actionName);
}
}

2、測(cè)試方法(傳統(tǒng)串行、串并行結(jié)合)

???? 假定各任務(wù)分別耗時(shí)為A(5秒)、B(5秒)、C(2秒)、D(1秒)、E(2秒)。則串行需用時(shí)5+5+2+1+2=15 秒,串并行結(jié)合(A、B -> C,A -> D,B -> E) 需用時(shí) 5+2 = 7 秒.

測(cè)試程序如下:

/// <summary>
/// 按設(shè)計(jì)的順序測(cè)試(同時(shí)考慮串行與并行): A、B -> C,A -> D,B -> E
/// </summary>
public static void SortTaskMethod()
{
Console.WriteLine("--------------[串行]--------------");
(new TestAction("A", 5)).Do();
(new TestAction("B", 5)).Do();
(new TestAction("C", 2)).Do();
(new TestAction("D", 1)).Do();
(new TestAction("E", 2)).Do();

Console.WriteLine("--------------[多任務(wù)]--------------");
TaskFactory factory = new TaskFactory();
Task a = factory.StartNew((new TestAction("A", 5)).Do);
Task b = factory.StartNew((new TestAction("B", 5)).Do);
Task c = factory.ContinueWhenAll(new Task[] { a, b }, ((preTasks) => (new TestAction("C", 2)).Do()));
Task d = factory.ContinueWhenAll(new Task[] { a }, ((preTasks) => (new TestAction("D", 1)).Do()));
Task e = factory.ContinueWhenAll(new Task[] { b }, ((preTasks) => (new TestAction("E", 2)).Do()));
}

3、執(zhí)行結(jié)果截圖

?

結(jié)論:與測(cè)試預(yù)想結(jié)果一致

實(shí)現(xiàn)的關(guān)鍵代碼:

// 聲明并獲取一個(gè)Task工廠實(shí)例

TaskFactory factory = new TaskFactory();

// 利用工廠創(chuàng)建一個(gè)任務(wù),并執(zhí)行指定的方法

Task a = factory.StartNew((new TestAction("A", 5)).Do);

// 利用工廠創(chuàng)建后續(xù)任務(wù)(根據(jù)前置任務(wù)),并執(zhí)行指定的方法

Task c = factory.ContinueWhenAll(new Task[] { a, b }, ((preTasks) => (new TestAction("C", 2)).Do()));


請(qǐng)注意以上使用工廠方式獲得的任務(wù)實(shí)例,與之前介紹的Parallel.Invoke 方式,二者有很重要的區(qū)別:工廠方式獲取任務(wù)實(shí)例后即分配給系統(tǒng)委托,不受當(dāng)前調(diào)用的方法約束;但invoke方式,括號(hào)內(nèi)部聲明的多個(gè)任務(wù),必須全部執(zhí)行結(jié)束,才會(huì)跳出invoke,回到當(dāng)前調(diào)用的方法中。




?

總結(jié)

以上是生活随笔為你收集整理的.Net Framework 4.0 中利用Task实现并行处理、串并行混合处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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