2012-05-16 45 views
5

Tôi khá mới mẻ đối với Đa luồng và chỉ chơi cùng với nó trong quá khứ. Nhưng tôi tò mò nếu nó có thể có một danh sách các mảng byte trên một chủ đề chính và vẫn có thể thêm vào danh sách đó trong khi tạo mảng byte mới trong một chủ đề riêng biệt. Ngoài ra, tôi sẽ sử dụng một vòng lặp for-each sẽ đi qua một danh sách các biểu mẫu sẽ được sử dụng để phân tích cú pháp vào mảng byte. Vì vậy, về cơ bản một mã giả sẽ giống như thế này ...Cách thêm vào Danh sách khi sử dụng Đa luồng?

reports = new List(); 

foreach (form in forms) 
{ 
    newReport = new Thread(ParseForm(form)); 
    reports.Add(newReport); 

} 

void ParseForm(form) 
{ 
    newArray = new byte[]; 
    newArray = Convert.ToBytes(form); 
    return newArray; 
} 

Hy vọng rằng mã giả ở trên có ý nghĩa gì đó. Nếu bất cứ ai có thể cho tôi biết nếu điều này là có thể và chỉ cho tôi theo hướng của một ví dụ tốt, tôi chắc chắn rằng tôi có thể tìm ra mã thực tế.

+0

Quên đề cập đến, dịch vụ web đang sử dụng .Net 3.5 nên tôi không tin Công việc có sẵn. – jhorton

Trả lời

3

Nếu bạn cần truy cập vào một bộ sưu tập từ nhiều chủ đề, bạn có nên đồng bộ hóa sử dụng, hoặc sử dụng một SynchronizedCollection nếu bạn. Phiên bản NET là 3.0 hoặc cao hơn.

Dưới đây là một cách để làm cho bộ sưu tập truy cập vào chủ đề của bạn:

SynchronizedCollection reports = new SynchronizedCollection(); 

foreach (form in forms) { 
    var reportThread = new Thread(() => ParseForm(form, reports)); 
    reportThread.Start(); 
} 

void ParseForm(Form form, SynchronizedCollection reports) { 
    newArray = new byte[]; 
    newArray = Convert.ToBytes(form); 
    reports.Add(newArray); 
} 

Nếu bạn đang ở trên NET 4 hoặc mới hơn, một sự thay thế tốt hơn để quản lý bài của bạn bằng tay được trình bày bởi các lớp khác nhau của System.Threading.Tasks không gian tên. Cân nhắc khám phá giải pháp thay thế này trước khi quyết định triển khai luồng của bạn.

+0

Cảm ơn, tôi sẽ phải thử SynchronizedCollection kể từ khi tôi vẫn còn trên 3,5. – jhorton

+0

Tôi có cần đặt tham chiếu cho SynchronizedCollection không? Tôi có các báo cáo sử dụng cho Collections.Genereric và Threading. Và tôi đã kiểm tra rằng nó đang sử dụng 3.5, nhưng tôi không nhận được một SynchronizedCollection. – jhorton

+0

@jhorton Bạn cần thêm tham chiếu vào 'System.ServiceModel'. – dasblinkenlight

0

Why is enumerate files returning the same file more than once?

Kiểm tra xem. Nó cho thấy tôi nghĩ chính xác những gì bạn muốn làm.

Tạo danh sách trên chuỗi chính rồi thêm vào danh sách từ một chuỗi khác. bạn sẽ cần

using System.Threading.Tasks 

-

Files.Clear(); //List<string> 

Task.Factory.StartNew(() => 
{ 
     this.BeginInvoke(new Action(() => 
     { 
      Files.Add("Hi"); 
     })); 
}); 
+1

Nó chỉ hoạt động nếu ** this ** là một System.Windows.Forms.Control (hoặc các lớp dẫn xuất). Nó không phải là một cơ chế đồng bộ hóa mà là một cách để tương tác với giao diện người dùng từ các chủ đề khác. –

+0

Không thể tranh luận với điều đó. –

2

Trong trước khi chúng tôi nhận ra đó là Net 3.5, giữ cho tài liệu tham khảo trên Net 4

Nếu bạn không cần bất kỳ thứ tự trong danh sách, "sửa chữa" dễ dàng là sử dụng lớp ConcurrentBag<T> thay vì danh sách. Nếu bạn cần thêm đơn hàng, cũng có bộ sưu tập ConcurrentQueue<T>.

Nếu bạn thực sự cần một thứ gì đó tùy chỉnh hơn, bạn có thể triển khai bộ sưu tập chặn của riêng mình bằng cách sử dụng BlockingCollection <T>. Here's a good article về chủ đề.

Bạn cũng có thể sử dụng Parallel.Foreach để tránh việc tạo ra chủ đề rõ ràng quá:

private void ParseForms() 
{ 
    var reports = new ConcurrentBag<byte[]>(); 
    Parallel.ForEach(forms, (form) => 
           { 
            reports.Add(ParseForm(form)); 
           }); 

} 

private byte[] ParseForm(form) 
{ 
    newArray = new byte[]; 
    newArray = Convert.ToBytes(form); 
    return newArray; 
} 
+0

ConcurrentBag có chỉ 4.0 và cao hơn không? – jhorton

+0

Có, bạn cũng đã thấy ghi chú của mình. Điều này là ridiculously dễ dàng trong. Net 4.0 nếu bạn có thể sử dụng nó. –

+0

Tôi phải đồng ý với bạn ở đó. Tôi không chắc tại sao họ chưa nâng cấp dịch vụ này lên 4.0. Mọi thứ khác đang sử dụng nó. – jhorton

0

Dưới đây là một bộ sưu tập chặn đơn giản (dưới dạng hàng đợi) mà tôi vừa mới bỏ qua kể từ khi bạn không có quyền truy cập C# 4.0. Nó có khả năng kém hiệu quả hơn 4.0 bộ sưu tập đồng thời, nhưng nó sẽ hoạt động tốt. Tôi đã không thực hiện lại tất cả các phương thức Queue, chỉ cần enqueue, dequeue và peek. Nếu bạn cần những người khác và không thể tìm ra cách họ sẽ được thực hiện chỉ đề cập đến nó trong các ý kiến.

Khi bạn có bộ sưu tập chặn hoạt động, bạn có thể chỉ cần thêm vào bộ sưu tập đó từ chủ đề của nhà sản xuất và loại bỏ nó khỏi chủ đề người tiêu dùng.

public class MyBlockingQueue<T> 
{ 
    private Queue<T> queue = new Queue<T>(); 
    private AutoResetEvent signal = new AutoResetEvent(false); 
    private object padLock = new object(); 

    public void Enqueue(T item) 
    { 
     lock (padLock) 
     { 
      queue.Enqueue(item); 
      signal.Set(); 
     } 
    } 

    public T Peek() 
    { 
     lock (padLock) 
     { 
      while (queue.Count < 1) 
      { 
       signal.WaitOne(); 
      } 

      return queue.Peek(); 
     } 
    } 

    public T Dequeue() 
    { 
     lock (padLock) 
     { 
      while (queue.Count < 1) 
      { 
       signal.WaitOne(); 
      } 

      return queue.Dequeue(); 
     } 
    } 
} 
Các vấn đề liên quan