Tôi đang cố gắng hiểu rõ hơn về tùy chọn Async và Parallel mà tôi có trong C#. Trong các đoạn dưới đây, tôi đã bao gồm 5 phương pháp tôi gặp nhất. Nhưng tôi không chắc chắn đó để lựa chọn - hoặc tốt hơn nữa, những gì tiêu chí để xem xét khi lựa chọn:C# Tùy chọn không đồng bộ để xử lý danh sách
Phương pháp 1: Nhiệm vụ
(xem http://msdn.microsoft.com/en-us/library/dd321439.aspx)
Calling StartNew là chức năng tương đương để tạo một Task bằng cách sử dụng một trong các hàm khởi tạo của nó và sau đó gọi Start để lên lịch cho nó để thực thi. Tuy nhiên, trừ khi tạo và lập lịch phải được tách ra, StartNew là phương pháp được khuyến nghị cho cả sự đơn giản và hiệu suất.
Khởi động của TaskFactory Phương thức mới nên là cơ chế ưu tiên để tạo và lập lịch nhiệm vụ tính toán, nhưng đối với các trường hợp cần phải tạo và lập lịch biểu, có thể sử dụng phương thức khởi tạo và phương pháp Bắt đầu của nhiệm vụ nhiệm vụ thực hiện sau này.
// using System.Threading.Tasks.Task.Factory
void Do_1()
{
var _List = GetList();
_List.ForEach(i => Task.Factory.StartNew(_ => { DoSomething(i); }));
}
Cách 2: QueueUserWorkItem
(thấy http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx)
Bạn có thể xếp hàng như nhiều yêu cầu bơi thread như bộ nhớ hệ thống cho phép. Nếu có nhiều yêu cầu hơn luồng chủ đề của chuỗi, yêu cầu bổ sung vẫn được xếp hàng đợi cho đến khi chuỗi chủ đề chuỗi trở nên khả dụng.
Bạn có thể đặt dữ liệu theo phương thức đã xếp hàng trong trường thể hiện của lớp mà phương thức được xác định hoặc bạn có thể sử dụng quá tải QueueUserWorkItem (WaitCallback, Object) chấp nhận đối tượng chứa dữ liệu cần thiết.
// using System.Threading.ThreadPool
void Do_2()
{
var _List = GetList();
var _Action = new WaitCallback((o) => { DoSomething(o); });
_List.ForEach(x => ThreadPool.QueueUserWorkItem(_Action));
}
Phương pháp 3: Parallel.Foreach
(xem: http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx)
Lớp Parallel cung cấp dữ liệu thư viện dựa trên thay thế song song cho các hoạt động phổ biến như cho vòng lặp, cho mỗi vòng lặp và thực hiện một tập hợp các câu lệnh.
Đại biểu cơ thể được gọi một lần cho mỗi phần tử trong nguồn có thể đếm được. Nó được cung cấp với phần tử hiện tại làm tham số.
// using System.Threading.Tasks.Parallel
void Do_3()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
Parallel.ForEach(_List, _Action);
}
Phương pháp 4: IAsync.BeginInvoke
(xem: http://msdn.microsoft.com/en-us/library/cc190824.aspx)
BeginInvoke là không đồng bộ; do đó, điều khiển trả về ngay lập tức đối tượng gọi sau khi nó được gọi.
// using IAsync.BeginInvoke()
void Do_4()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
_List.ForEach(x => _Action.BeginInvoke(x, null, null));
}
Phương pháp 5: BackgroundWorker
(xem: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
Để thiết lập cho một hoạt động nền, thêm một event handler cho sự kiện DoWork. Gọi hoạt động tốn thời gian của bạn trong trình xử lý sự kiện này. Để bắt đầu hoạt động, hãy gọi RunWorkerAsync. Để nhận thông báo cập nhật tiến trình, hãy xử lý sự kiện ProgressChanged. Để nhận được thông báo khi thao tác hoàn tất, hãy xử lý sự kiện RunWorkerCompleted.
// using System.ComponentModel.BackgroundWorker
void Do_5()
{
var _List = GetList();
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
arg.Result = arg.Argument;
DoSomething(arg.Argument);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
_List.Remove(arg.Result);
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
};
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
}
}
Tôi cho rằng được những tiêu chí rõ ràng sẽ là:
- Là bất kỳ tốt hơn so với khác để thực hiện?
- Có tốt hơn cách khác để xử lý lỗi không?
- Có tốt hơn điểm khác để theo dõi/phản hồi không?
Nhưng, cách bạn chọn? Cảm ơn trước vì thông tin chi tiết của bạn.
Bạn cũng có thể xem System.Reactive (phần mở rộng phản hồi hoặc rx.net). – lbergnehr
Và bạn thậm chí không chạm vào CTP Async! :-) – xanatos
Đó là sự thật, nhưng tôi đã gắn bó với C# 4. Điểm tốt, mặc dù. –