2009-07-17 25 views
32

Đối tượng BackgroundWorker cho phép chúng ta chuyển một đối số duy nhất vào DoWorkEventHandler.Thay thế cho BackgroundWorker chấp nhận nhiều hơn một đối số?

// setup/init: 
BackgroundWorker endCallWorker = new BackgroundWorker(); 
endCallWorker.DoWork += new DoWorkEventHandler(EndCallWorker_DoWork); 
... 
endCallWorker.RunWorkerAsync(userName); 

// the handler: 
private void EndCallWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string userName = e.Argument as string; 
    ... 
} 

Để vượt qua nhiều đối số, tôi phải bọc chúng trong một đối tượng, như mảng chuỗi nghèo này:

// setup/init: 

BackgroundWorker startCallWorker = new BackgroundWorker(); 
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork); 
... 
startCallWorker.RunWorkerAsync(new string[]{userName, targetNumber}); 


// the handler: 
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    string[] args = e.Argument as string[]; 
    string userName = args[0]; 
    string targetNumber = args[1]; 
} 

Có một đối tượng hoặc mô hình cho phép chúng ta vượt qua nhiều đối số độc đáo, hoặc lý tưởng, viết chữ ký của riêng mình?

Trả lời

45

Bạn có thể sử dụng một đóng cửa (Lambda):

backgroundWorker.DoWork += (s, e) => MyWorkMethod(userName, targetNumber); 

Hoặc với đại biểu (phương pháp vô danh) Cú pháp:

backgroundWorker.DoWork += 
    delegate(object sender, DoWorkEventArgs e) 
    { 
     MyWorkMethod(userName, targetNumber); 
    }; 
+0

bạn có thể xây dựng trên cách làm việc này? (đặc biệt là "(s, e)" ... tại sao chúng được khai báo?) –

+0

Tôi thích điều này rất nhiều - Đối với trường hợp sử dụng của tôi, nó hoạt động tốt, nhưng các ứng dụng phức tạp hơn có thể có vấn đề, tức là tôi cần truy cập vào tham số giá trị (tên người dùng và targetNumber) tại thiết lập/init. –

+1

Vui mừng được trợ giúp (và một số văn bản khác). –

0

Tại sao không có đối tượng "một" được chuyển thành một mảng thông số? Bạn chỉ cần đưa nó trở lại mảng bên trong phương thức từ tham số đối tượng.

2

lẽ vượt qua một hàm lambda như đối tượng của bạn? Sau đó, bạn sẽ gọi nó trong trình xử lý DoWork.

endCallWorker.RunWorkerAsync(new Action(() => DelegatedCallTarget(userName, targetNumber))); 
+0

bạn có thể chỉ cho tôi cách tôi mở chúng trong bộ xử lý không? –

3

Đối tượng có thể là danh sách hoặc mảng hoặc một số loại như vậy. Chỉ cần làm cho đối tượng của bạn một thùng chứa một số loại, sau đó đúc trong BackgroundWorker. Bạn cần phải chắc chắn rằng bạn luôn luôn đi qua trong cùng một loại mặc dù.

+0

+ McAden Nếu các nhà thiết kế thư viện xử lý hai đối số, tại sao không phải ba, bốn, v.v ...? Giải pháp là để xử lý một, và rằng một trong những có thể là một đối tượng phức tạp tùy ý. – DougN

12

Có vấn đề gì khi sử dụng đối tượng đã nhập?

internal class UserArgs 
{ 
    internal string UserName { get; set; } 
    internal string TargetNumber { get; set; } 
} 

var args = new UserArgs() {UserName="Me", TargetNumber="123" }; 
startCallWorker.RunWorkerAsync(args); 
+0

Điều này đẹp hơn mảng chuỗi [] của tôi, nhưng vẫn - tôi không muốn khai báo một lớp khác chỉ để chuyển đối số vào hàm của riêng tôi. Điều này xảy ra trong rất nhiều trình xử lý tích hợp khác trong .NET - Tôi đoán tôi đang tìm một mẫu nhất quán không gây ô nhiễm mã của tôi với các lớp trình bao bọc vô dụng. –

+2

C# 4.0 có bộ tuple có thể chứa nhiều hơn một arg. Vui lòng tham khảo câu trả lời của tôi cho câu hỏi này. –

4

thay vì đối tượng đã nhập. C# 4.0 cung cấp cho chúng tôi tuple. Chúng ta có thể sử dụng một tuple để giữ nhiều arg. Sau đó, không cần phải khai báo một lớp mới.

1

Tạo một lớp chứa tất cả các đối số của bạn

Class MyClass 
{ 
    private string m_Username = string.Empty; 
    private int m_Targetnumber; 

    public MyClass(){} 

    public string Username 
    { 
     get { return m_Username; } 
     set { m_Username = value; } 
    } 

    public int TargetNumber 
    { 
     get { return m_TargetNumber; } 
     set { m_TargetNumber = value; } 
    } 
} 



// setup/init: 

BackgroundWorker startCallWorker = new BackgroundWorker(); 
startCallWorker.DoWork += new DoWorkEventHandler(StartCallWorker_DoWork); 
... 

MyClass thisClass = new MyClass(); 
thisClass.Username = "abcd"; 
thisClass.TargetNumber = 1234; 
startCallWorker.RunWorkerAsync(thisClass); 


// the handler: 
private void StartCallWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyClass args = (MyClass)e.Argument; 
    string userName = args.Username; 
    string targetNumber = args.TargetNumber; 
} 
Các vấn đề liên quan