2013-07-02 33 views
19

Ngay bây giờ tôi đang sử dụng mã sau để thêm các chuỗi đã xếp hàng. Tôi không thích nó. Và các đồng nghiệp của tôi sẽ không vì họ không biết rõ C#. Tất cả tôi muốn là tất nhiên để xếp hàng một phương pháp được thực hiện trong một chủ đề mới.C# - ThreadPool QueueUserWorkItem Sử dụng?

private static void doStuff(string parameter) 
{ 
    // does stuff 
} 

// call (a) 
ThreadPool.QueueUserWorkItem(a => doStuff("hello world")); 
// call (b) 
ThreadPool.QueueUserWorkItem(delegate { doStuff("hello world"); }); 

Vì vậy, có các biến thể sử dụng khác của ThreadPool.QueueUserWorkItem?

Tốt nhất là một cuộc gọi 1 đường khác. Nếu có thể, hãy sử dụng Func<> hoặc Action<>.


EDIT: Có (b) từ các câu trả lời và nhận xét và tôi thích nó tốt hơn rồi.

+2

có vấn đề gì với ThreadPool.QueueUserWorkItem() trong trường hợp của bạn? –

+1

bạn có thể sử dụng từ khóa "ủy nhiệm". Một cái gì đó như, ThreadPool.QueueUserWorkItem (delegate {doStuff ("");}). Cũng giống như phương pháp trên, nhưng như bạn muốn, đây chỉ là một cách khác để làm điều đó .. –

+1

Tại sao trên thế giới bạn nghĩ rằng cú pháp đại biểu là sạch hơn lambdas !? –

Trả lời

12

Câu trả lời cho câu hỏi của bạn phụ thuộc vào cách bạn thiết kế ứng dụng. Bạn có đặt nó bên trong một dự án chung? bạn không muốn trên đầu một hoạt động đơn giản.

Nhưng, bạn có thể tạo một cuộc gọi chung cho ThreadPool QueueUserItem nhận params, 1 param, 2 param, vv .. Điều này là tốt thay vì gửi một chuỗi đơn giản và bị hạn chế.

này làm thế nào bạn impl một thông số QueueUserItem với WaitCallback:

ThreadPool.QueueUserWorkItem(
    new WaitCallback(delegate(object state) 
    { YourMethod(Param1, Param2, Param3); }), null); 

lấy từ C# Execute Method (with Parameters) with ThreadPool

Và một số liên kết cho ý tưởng:
http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
Generic ThreadPool in .NET
Difference between delegate.BeginInvoke and using ThreadPool threads in C#

+0

Điều đó cũng có thể thực hiện được với 'Func' hoặc' Action' hoặc không có phần gọi thêm? – Bitterblue

+0

Nó sẽ có thể, khi bạn xây dựng WaitCallback, không gửi một "đại biểu" đơn giản, gửi đại biểu của riêng bạn thay thế. * nhưng *, làm thế nào để bạn mong đợi để có được kết quả trở lại? thường khi gửi hoạt động đến chuỗi công nhân, bạn không mong đợi để có được kết quả, chỉ để đảm bảo công việc được thực hiện. Bạn có thể đạt được điều này bằng cách thực hiện một mẫu không đồng bộ. http://www.c-sharpcorner.com/UploadFile/rmcochran/multithreadasyncwebservice05262007094719AM/multithreadasyncwebservice.aspx – ilansch

13

Tôi không hoàn toàn chắc chắn về loại cú pháp bạn đang tìm kiếm, nhưng nếu bạn không thích số a chưa sử dụng trong ví dụ của mình, tại sao không sử dụng Task thay thế?

Task.Run(() => doStuff("hello world")); 

Nó không thực sự có vẻ tốt hơn nhiều, nhưng ít nhất nó không có số nhận dạng không sử dụng.

Lưu ý: Task.Run() là .Net 4.5 hoặc mới hơn. Nếu bạn đang sử dụng .Net 4 bạn phải làm:

Task.Factory.StartNew(() => doStuff("hello world")); 

không ngắn.

Cả hai bên trên đều sử dụng nhóm chủ đề.

Nếu bạn thực sự phải tránh sử dụng một lambda, bạn có thể sử dụng một đại biểu vô danh (mà @nowhewhomustnotbenamed đã đề cập):

Task.Run(delegate { doStuff("Hello, World!"); }); 

Nhưng quan điểm đó là những gì? Nó ít dễ đọc hơn!

+0

Thực ra tôi muốn tránh điều Lambda. – Bitterblue

+0

@ mini-me Tôi cũng đã thêm một ví dụ tránh sử dụng lambda ... Đó là tệ hơn tho, IMO. –

+9

@ mini-me Biểu thức Lambda khá nhiều thay thế các đại biểu vô danh khá lâu trước đây. Vì vậy, bạn sẽ làm tốt để làm quen với họ sớm hơn là sau này. – nashwan

2

gì về điều này ?

class Program 
{ 
    static void Main(string[] args) 
    { 
     ThreadPool.QueueUserWorkItem(MyWork, "text"); 
     Console.ReadKey(); 
    } 

    private static void MyWork(object argument) 
    { 
     Console.WriteLine("Argument: " + argument); 
    } 
} 

Hoặc nếu bạn không muốn bị hạn chế chữ ký và có cách đơn giản để đưa phương pháp vào chuỗi, bạn có thể làm như vậy.Đối với các phương pháp làm và không trả lại giá trị và có tối đa 6 các thông số nó sẽ yêu cầu bạn xác định 12 tình trạng quá tải nếu tôi không nhầm.Nó đòi hỏi một chút công việc lên phía trước, nhưng là đơn giản hơn để sử dụng.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var myClass = new MyClass(); 
     myClass.DoWork(); 
     Console.ReadKey(); 
    } 
} 

public static class ObjectThreadExtension 
{ 
    public static void OnThread(this object @object, Action action) 
    { 
     ThreadPool.QueueUserWorkItem(state => 
     { 
      action(); 
     }); 
    } 

    public static void OnThread<T>(this object @object, Action<T> action, T argument) 
    { 
     ThreadPool.QueueUserWorkItem(state => 
     { 
      action(argument); 
     }); 
    } 
} 

public class MyClass 
{ 
    private void MyMethod() 
    { 
     Console.WriteLine("I could have been put on a thread if you like."); 
    } 

    private void MySecondMethod(string argument) 
    { 
     Console.WriteLine(argument); 
    } 

    public void DoWork() 
    { 
     this.OnThread(MyMethod); 
     this.OnThread(MySecondMethod, "My argument"); 
    } 
} 
+0

Điều này sẽ là một người chiến thắng đối với tôi, nếu nó không phải là chữ ký hạn chế như thế. Nhưng vẫn tuyệt vời khi chỉ cho nó một phương pháp và được thực hiện với nó. – Bitterblue

+0

@Bitterblue Tôi đã thêm một phương pháp thứ hai. Một chút công việc lên phía trước, nhưng dễ dàng nhất trong sử dụng theo ý kiến ​​của tôi. –

Các vấn đề liên quan