Most popular
-
Trigger คืออะไร? ท่านที่เคยเขียนโปรแกรม และเคยใช้ Event handle ก็จะนึกถึงการทำงานของ Trigger ไม่ยาก Trigger ก็คือ Code คำสั่ง SQL ที่ถูกสร...
-
MySQL Workbench ที่ผู้เขียนใช้ทำตัวอย่างเป็น Version 5.2.34 CE สำหรับ Windows 32 bit หรือตัวใหม่กว่าก็ได้ครับ ดาวน์โหลดได้ที่นี่ http://www...
-
คนที่มีภาพใน facebook เยอะๆก็คงจะต้องการย้ายภาพไปมา บางทีก็เอาภาพบนกระดานเก็บลงอัลบั้ม บางทีก็หาไม่เจอว่าจะย้ายได้ยังไง การย้ายอัลบั้มไม่ยา...
-
Tier คำนี้เมื่อแปลออกมาจะแปลได้ว่า "ชั้น" Tier ในวงการ Software ก็มีความหมายคล้ายกัน สำหรับท่านที่ยังไม่เข้าใจขอแนะนำง่ายๆ โดยให้...
-
หลายท่านคงเคยเล่น หรือไม่ก็รู้จักชื่อเสียงเรียงนามของเกมนี้กันบ้าง หลังจากที่โด่งดังมาจากวงการ Tablet และ Smart Phone ก็ได้ออก Version ที่เล...
วันพฤหัสบดีที่ 29 กันยายน พ.ศ. 2554
การรันคำสั่งด้วย Parallel ใน .net 4
ซึ่งใน .net 4 จะมี library ที่ชื่อ System.Threading.Tasks ให้เราใช้ในการจัดการกับ Task หรือคำสั่งต่างๆ เช่นเราต้องการจัดการกับเมธอดหลายๆ
เมธอดเพื่อให้ทำงานพร้อมกัน(Concurrency) เช่นมีเมธอด
A,B,C เราก็ใช้
Parallel.Invoke(A,B,C);
หรือ
Parallel.Invoke(()=>A(),
()=>B(),
()=>C()
);
ตัวอย่างการใช้งาน Parallel.Invoke เริ่มแรกให้เราทำการ using System.Threading.Tasks ก่อนแล้วเขียนคำสั่งต่างๆดังนี้
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
Parallel.Invoke(
() => A(),
() => B(),
() => C()
);
Console.ReadLine();
}
static void A()
{
Console.WriteLine("A");
}
static void B()
{
Console.WriteLine("B");
}
static void C()
{
Console.WriteLine("C");
}
}
}
ซึ่งผลลัพธ์เราจะได้
A
B
C
ในตัวอย่างนี้จะเป็นการสั่งให้โปรแกรมทำการเรียกใช้เมธอดทั้งสามพร้อมๆกัน ซึ่งถ้าเรามีเมธอดมากกว่านี้เราก็สามารถเรียกใช้ได้เหมือนกับการเรียกเมธอดในตัวอย่างนี้
ถึงแม้ว่าจะมีการเรียกใช้เมธอดให้เริ่มต้นทำงานพร้อมกันในแบบ Concurrency ก็ตามแต่เวลาที่ใช้ในการทำงานตามคำสั่งข้างในเมธอดแต่ละเมธอดจะไม่เท่ากันซึ่งเราสามารถ
วัดเวลาในการทำงานได้โดยใช้ Stopwatch ดังนี้
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
Parallel.Invoke(
() => A(),
() => B(),
() => C()
);
Console.ReadLine();
}
static void A()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("A");
Console.WriteLine("elapsed time of A is " + watch.Elapsed.TotalSeconds);
}
static void B()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("B");
Console.WriteLine("elapsed time of B is " + watch.Elapsed.TotalSeconds);
}
static void C()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("C");
Console.WriteLine("elapsed time of C is " + watch.Elapsed.TotalSeconds);
}
}
}
ซึ่งผลลัพธ์เราจะได้ดังรูป
จากรูปที่ 1 ถ้าเราเพิ่ม Thread.Sleep เข้าไปที่เมธอด B โดยให้ทำการ sleep เป็นเวลา 4 วิ ผลลัพธ์ที่ได้เราจะเห็นเวลาที่เมธอด B ทำงานตั้งแต่เริ่มต้น
ถึงสิ้นสุดนานกว่าเมธอดอื่นที่ไม่ได้ใช้ Thread.Sleep และจะทำงานเสร็จสิ้นเป็นเมธอดสุดท้ายด้วยดังนี้
static void B()
{
var watch = Stopwatch.StartNew();
Thread.Sleep(4000);
Console.WriteLine("B");
Console.WriteLine("elapsed time of B is " + watch.Elapsed.TotalSeconds);
}
ผลลัพธ์เราจะได้ดังรูป
ซึ่งจากตัวอย่างนี้เราจะเห็นว่าถึงแม้เริ่มต้นทำงานพร้อมกันแต่ระยะเวลาหรือความเร็วในการประมวลผลคำสั่งแต่ละเมธอดจะไม่เท่ากันขึ้นอยู่กับราย
ละเอียดภายในเมธอดว่ามีมากน้อยเพียงใดซึ่งถ้าเราเห็นว่าเมธอดไหนทำงานช้ามากเราก็สามารถแบ่งการทำงานของเมธอดนั้นออกเป็น parallel หรือสั่งให้ทำงานแบบคู่ขนานได้
ซึ่งจะทำให้เมธอดนั้นๆใช้เวลาที่น้อยลงหรือมีการทำงานที่เร็วขึ้น
การใช้ Task
ก่อนหน้านี้เราได้ใช้ Parallel.Invokeในการเรียกเมธอดทำงานพร้อมๆกัน ซึ่งในส่วนนี้จะมีอีกวิธีที่สามารถสั่งให้โปรแกรมทำงานพร้อมๆกันด้วยคลาสที่ชื่อ Task
ซึ่งในการใช้ Task นั้นไม่ยุ่งยากโดยถ้าเรามีหลายๆเมธอดแล้วต้องการให้เมธอดเหล่านี้เริ่มทำงานพร้อมๆกัน เราสามารถแบ่งการทำงานของเมธอดออกเป็น Task แต่ละ Task
ไปได้ เช่นมี 3 เมธอดคือ A,B,C ถ้าต้องการแบ่งเป็น Task เราก็เขียนได้ดังนี้
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
var t1 = new Task(()=>A());
var t2 = new Task(() => B());
var t3 = new Task(() => C());
t1.Start();
t2.Start();
t3.Start();
Task.WaitAll(t1, t2, t3);
Console.WriteLine("Finished all Tasks");
Console.ReadLine();
}
static void A()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("A");
Console.WriteLine("elapsed time of A is " + watch.Elapsed.TotalSeconds);
}
static void B()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("B");
Console.WriteLine("elapsed time of B is " + watch.Elapsed.TotalSeconds);
}
static void C()
{
var watch = Stopwatch.StartNew();
Console.WriteLine("C");
Console.WriteLine("elapsed time of C is " + watch.Elapsed.TotalSeconds);
}
}
}
ในตัวอย่างนี้เริ่มแรกให้เราสร้าง Task ขึ้นมาก่อนโดยภายใน Task ก็จะมีการกำหนดเมธอดที่ต้องการใช้งาน Task จากนั้นเรียกคำสั่ง Start เพื่อทำการสั่งให้เริ่มทำงาน Task
จากนั้นจะมีคำสั่ง WaitAll เพื่อรอให้ทุก Task ทำงานเสร็จก่อนแล้วถึงจะทำการแสดงค่า Finished all Tasks
ซึ่งตรง WaitAll นี้เราสามารถกำหนดเวลาเพื่อให้โปรแกรมทำการรอได้เช่นถ้าการทำงานของ Task ทุก Task เกินเวลาที่กำหนดไว้ก็อาจจะให้แจ้งเตือนขึ้นมาว่า
Task ที่ทำงานนั้นใช้เวลาเกินกว่าทีกำหนด ซึ่งให้เขียนดังนี้
static void Main(string[] args)
{
var t1 = new Task(()=>A());
var t2 = new Task(() => B());
var t3 = new Task(() => C());
t1.Start();
t2.Start();
t3.Start();
if (!Task.WaitAll(new Task[] { t1, t2, t3 }, 4000))
{
Console.WriteLine("elapsed time > 4000 ms");
}
Console.WriteLine("Finished all Tasks");
Console.ReadLine();
}
ซึ่งในตัวอย่างนี้ถ้าเรารันโปรแกรมเราจะยังไม่เป็นคำสั่งในส่วนของ Console.WriteLine("elapsed time > 4000 ms");
เนื่องจากว่าทุก Task ใช้เวลาน้อยกว่า 4000 ms แต่ถ้าเราเพิ่ม Thread.Sleep ในเมธอดใดเมธอดหนึ่งให้ทำการ Sleep เป็นเวลา 5000 ms เช่นเพิ่ม
ตรงเมธอด A ดังนี้
static void A()
{
var watch = Stopwatch.StartNew();
Thread.Sleep(5000);
Console.WriteLine("A");
Console.WriteLine("elapsed time of A is " + watch.Elapsed.TotalSeconds);
}
ผลลัพธ์ที่ได้เราจะได้ดังรูป
ที่มา : คุณ paedotnet http://www.codetoday.net/default.aspx?g=posts&t=2945
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
อยากทราบว่าถ้าเป็น .net 3.5 จะเขียนแนวนี้ได้มั้ยครับ
ตอบลบอันนี้ยังไม่เคยลองแต่คิดว่าไม่ได้ครับ
ตอบลบเท่าที่ดู 4.0 จะมีอะไรใหม่ๆ มาแก้ไขความยุ่งยากของ 3.5 ครับ
ของ 3.5 ต้องใช้ Thread กับ delegate ค่อนข้างละเอียดและยาว