2010-03-17 32 views
41

Tôi đã cố gắng triển khai mẫu nhà sản xuất/người tiêu dùng trong C#. Tôi có một chuỗi người tiêu dùng theo dõi hàng đợi được chia sẻ và một chuỗi nhà sản xuất đặt các mục vào hàng đợi được chia sẻ. Chuỗi nhà sản xuất được đăng ký để nhận dữ liệu ... tức là, nó có một trình xử lý sự kiện, và chỉ ngồi xung quanh và đợi một sự kiện OnData kích hoạt (dữ liệu đang được gửi từ api của bên thứ 3). Khi nó nhận được dữ liệu, nó dính nó vào hàng đợi để người tiêu dùng có thể xử lý nó.Trong .NET, chuỗi sự kiện nào sẽ được xử lý?

Khi sự kiện OnData kích hoạt trong nhà sản xuất, tôi đã dự kiến ​​nó sẽ được xử lý bởi chuỗi sản xuất của tôi. Nhưng điều đó dường như không phải là những gì đang xảy ra. Sự kiện OnData có vẻ như đang được xử lý trên một chuỗi mới! Đây có phải là cách .net luôn hoạt động ... các sự kiện được xử lý theo chủ đề của riêng họ? Tôi có thể kiểm soát chuỗi nào sẽ xử lý các sự kiện khi chúng được nâng lên không? Điều gì xảy ra nếu hàng trăm sự kiện được nâng lên gần như đồng thời ... mỗi người sẽ có chủ đề riêng của mình?

+0

Nó có thể giúp đăng một số mã và/hoặc các lớp bạn đang sử dụng. –

+0

Bạn có đang nói về các sự kiện trong ý nghĩa từ khóa C# 'event' hoặc các sự kiện trong ý nghĩa' EventWaitHandle' không? Tôi nghĩ rằng bạn nên đăng một số mã số ... –

+0

@codeka: nó có vẻ giống như 'sự kiện', cho bài viết của mình. –

Trả lời

22

Trừ khi bạn tự mình sửa đổi, một sự kiện sẽ thực hiện trên bất kỳ chuỗi nào đang gọi nó; không có gì đặc biệt về cách các sự kiện được triệu gọi, và luồng sản xuất của bạn không có trình xử lý sự kiện, luồng sản xuất của bạn chỉ đơn giản nói "hey, khi bạn kích hoạt sự kiện này, hãy gọi hàm này". Không có gì trong đó gây ra sự kiện xảy ra trên thread đính kèm, cũng không phải trên thread riêng của nó (trừ khi bạn sử dụng BeginInvoke thay vì gọi đại biểu của sự kiện bình thường, nhưng điều này sẽ chỉ thực hiện nó trên ThreadPool).

74

Sau khi đọc lại câu hỏi, tôi nghĩ rằng tôi đã hiểu được sự cố ngay bây giờ. Về cơ bản, bạn đã có một cái gì đó như thế này:

class Producer 
{ 
    public Producer(ExternalSource src) 
    { 
     src.OnData += externalSource_OnData; 
    } 

    private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e) 
    { 
     // put e.Data onto the queue 
    } 
} 

Và sau đó bạn đã có một chuỗi tiêu dùng để kéo thứ đó ra khỏi hàng đợi đó. Vấn đề là sự kiện OnData được kích hoạt bởi đối tượng ExternalSource của bạn - trên bất kỳ chủ đề nào nó xảy ra đang chạy.

C# event s về cơ bản chỉ là một bộ sưu tập dễ sử dụng của đại biểu và "kích hoạt" sự kiện chỉ làm cho thời gian chạy lặp qua tất cả các đại biểu và kích hoạt chúng một lần.

Vì vậy, trình xử lý sự kiện OnData của bạn đang được gọi trên bất kỳ chuỗi nào ExternalSource đang chạy.

+1

Cảm ơn Codeka, bạn đã có nó chính xác. Tôi sẽ kiểm tra những gì các sự kiện externalSource đang xảy ra. Tôi đánh giá cao sự giúp đỡ. – Ben

+13

@Ben - Bạn nên đánh dấu phần này là câu trả lời được chấp nhận. Điều này sẽ giúp người khác thấy câu trả lời dễ dàng hơn. –

+1

mọi thứ khác nhau khi các sự kiện được kích hoạt bằng cách sử dụng Invoke và BeginInvoke..BeginInvoke gọi người đăng ký sự kiện trong một chuỗi khác từ threadpool (trong một chủ đề nền) –

7

Tăng sự kiện với Invoke giống như gọi một phương thức - nó được thực hiện trong cùng một chuỗi bạn đã tạo.

Tăng sự kiện với BeginInvoke sử dụng ThreadPool. Dưới đây là một số minor details

-3

bạn phải sử dụng bộ xử lý tự động cho vấn đề này ..... trong khi nhà sản xuất sản xuất tín hiệu, sau đó người tiêu dùng đặt lại tín hiệu và tiêu thụ .. ..

AutoResetEvent pro = new AutoResetEvent(false); 
AutoResetEvent con = new AutoResetEvent(true); 

public void produser() 
{ 

    while(true) 
    { 
     con.WaitOne(); 

     pro.Set(); 
    } 
} 

public void consumer() 
{ 
    while (true) 
    { 
    pro.WaitOne(); 
     .................**** 

    con.Set(); 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Thread th1 = new Thread(produser); 
    th1.Start(); 
    Thread th2 = new Thread(consumer); 
    th2.Start(); 
} 
Các vấn đề liên quan