2009-04-10 12 views
23

Đi qua hai tham số to a thread mới trên threadpool đôi khi có thể phức tạp, nhưng có vẻ như với các biểu thức lambda và các phương pháp vô danh, tôi có thể làm điều này:ThreadPool.QueueUserWorkItem với một biểu thức lambda và phương pháp vô danh

public class TestClass 
{ 
    public void DoWork(string s1, string s2) 
    { 
     Console.WriteLine(s1); 
     Console.WriteLine(s2); 
    } 
} 

try 
{ 
    TestClass test = new TestClass(); 
    string s1 = "Hello"; 
    string s2 = "World"; 
    ThreadPool.QueueUserWorkItem(
     o => test.DoWork(s1, s2) 
     ); 
} 
catch (Exception ex) 
{ 
    //exception logic 
} 

Bây giờ, tôi đã chắc chắn đơn giản hóa ví dụ này, nhưng những điểm này là chìa khóa:

  • Các đối tượng chuỗi được thông qua là không thay đổi và do đó threadsafe
  • Các s1 và s2 biến được khai báo w ithin phạm vi của khối thử, mà tôi thoát ngay lập tức sau khi xếp hàng công việc vào nhóm luồng, do đó các biến s1 và s2 không bao giờ được sửa đổi sau đó.

Có vấn đề gì với điều này không?

Cách khác là tạo lớp mới thực hiện loại không thay đổi với 3 thành viên: test, s1 và s2. Điều đó có vẻ giống như công việc phụ không có lợi ích tại thời điểm này.

+1

Tại sao bạn không viết 'o => test.DoWork (s1, s2)' thay vì định nghĩa dài dòng hơn? –

+0

@Mehrdad: Bởi vì tôi thực sự mới với các biểu thức lambda. ;) - cảm ơn! –

+0

@Mehrdad: Tôi đã thay đổi nó trong câu hỏi. –

Trả lời

16

Không có gì sai với điều này. Trình biên dịch cơ bản sẽ tự động thực hiện những gì bạn mô tả như là lựa chọn thay thế của bạn. Nó tạo ra một lớp để giữ các biến bị bắt (test, s1 và s2) và chuyển một cá thể ủy nhiệm tới lambda được biến thành một phương thức trên lớp ẩn danh. Nói cách khác, nếu bạn đã đi trước với thay thế của bạn, bạn sẽ kết thúc với soemthing rất giống với những gì trình biên dịch vừa tạo ra cho bạn.

2

Đó là cách hay để thực hiện. Tôi không thấy bất kỳ nhược điểm nào khi sử dụng lambdas. Nó đơn giản và sạch sẽ.

4

Ví dụ cụ thể này, không có gì sai ở đây. Trạng thái bạn đã chuyển vào luồng khác được chứa hoàn toàn và không có loại nào liên quan đến bất kỳ vấn đề nào về mối quan hệ luồng.

+0

Còn về mô hình chung thì sao? Làm thế nào sẽ biết nếu một loại có vấn đề ái lực chủ đề? –

+0

Về cơ bản, bạn đang hỏi liệu lớp học có an toàn hay không. Trong thực hiện cụ thể của tôi (trong hầu hết các trường hợp) tôi đang sử dụng các đối tượng không thay đổi sâu sắc để làm cho chúng an toàn hơn. Các cách khác để làm cho các đối tượng trở nên an toàn hơn là sử dụng khóa, v.v. –

+0

@Jelel nếu một loại có vấn đề về sở thích luồng, bạn là bánh mì nướng. Bạn không thể làm gì với nó trên một chủ đề riêng biệt. Các mô hình chung là âm thanh mặc dù (tôi sử dụng nó thường xuyên) – JaredPar

2

Những gì bạn đang xem được gọi là đóng. Là chuckj states, trình biên dịch tạo ra một lớp tại thời gian biên dịch tương ứng với các thành viên được truy cập bên ngoài đóng.

Điều duy nhất bạn phải lo lắng là nếu bạn có tham số ref hoặc out. Trong khi các chuỗi là bất biến, các tham chiếu tới chúng (hoặc bất kỳ biến nào) là NOT.

1

Một vấn đề tiềm năng với mô hình là nó rất hấp dẫn để mở rộng nó thành một cái gì đó nhiều hơn-generic nhưng kém an toàn như thế này (đầu số- không mong đợi nó để làm việc):

public static void QueueTwoParameterWorkItem<T1, T2>(T1 value1, T2 value2, workDelegate<T1,T2> work) 
{ 
    try 
    { 
     T1 param1 = value1; 
     T2 param2 = value2; 
     ThreadPool.QueueUserWorkItem(
      (o) => 
      { 
       work(param1, param2); 
      }); 
    } 
    catch (Exception ex) 
    { 
     //exception logic 
    } 
} 
+0

Trong trường hợp của tôi, tôi có một lớp cơ sở không thay đổi sâu sắc mà tôi có thể sử dụng để đóng đinh T1 và T2 ... để bạn có thể thực hiện công việc này trong trường hợp cụ thể của tôi. Nếu bạn không hiểu các vấn đề về luồng, thì việc sử dụng threadpool vẫn nằm ngoài câu hỏi. –

+0

Đồng ý: trường hợp cụ thể của bạn là tốt. Đó là khi bạn thực hiện nó như là một mô hình chung chung có những mối quan tâm. –