2009-07-17 3 views
32

BackgroundWorker 개체를 사용하면 단일 인수를 DoWorkEventHandler에 전달할 수 있습니다.둘 이상의 인수를 허용하는 BackgroundWorker 대신 사용할 수 있습니까?

// 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; 
    ... 
} 

내가이 가난한 문자열 배열과 같은 객체에서 그들을 포장해야하며, 여러 인수를 전달하려면 :

// 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]; 
} 

우리가 잘, 또는 이상적으로 여러 인수를 전달할 수 있도록 다른 객체 또는 패턴이 있는가, 우리 서명을 써요?

답변

45

당신은 폐쇄 (람다)를 사용할 수 있습니다

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

를 보유하는 클래스를 만드시겠습니까? (특히 "(s, e)"... 왜 선언 되었습니까?) –

+0

저는 이것을 많이 좋아합니다. - 유스 케이스의 경우 훌륭하게 작동하지만 더 복잡한 응용 프로그램에 문제가있을 수 있습니다. 즉 매개 변수에 액세스해야합니다. 값 (username 및 targetNumber)은 setup/init에서 확인하십시오. –

+1

도움이되기를 기쁘게 생각합니다 (그리고 더 많은 텍스트). –

0

"하나의"객체가 매개 변수의 배열로 전달되지 않는 이유는 무엇입니까? object 매개 변수의 메서드 내에서 다시 배열로 캐스트하면됩니다.

2

어쩌면 당신의 개체로 람다 함수를 전달합니다

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

또는 대리인 (익명 메소드) 구문

? 그런 다음 DoWork 핸들러에서 호출합니다.

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

처리기에서 처리기를 사용하지 않는 방법을 보여줄 수 있습니까? –

3

개체는 목록이나 배열 등일 수 있습니다. 그냥 개체를 일종의 컨테이너로 만든 다음 BackgroundWorker 내에서 캐스트합니다. 당신은 항상 당신이 동일한 유형을 통과하고 있는지 확인해야합니다.

+0

+ McAden 도서관 디자이너가 두 가지 주장을 처리한다면 왜 3, 4 등이 아닌가? 해결책은 하나를 다루는 것이었고, 하나는 임의의 복잡성의 대상이 될 수 있습니다. – DougN

12

입력 된 개체 사용시 문제점은 무엇입니까?

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

이것은 string [] 배열보다 좋지만, 여전히 다른 클래스가 인자를 내 자신의 함수에 전달한다고 선언하고 싶지는 않습니다. 이것은 .NET의 다른 많은 내장 핸들러에서 발생합니다. 쓸데없는 래퍼 클래스로 코드를 오염시키지 않는 일관된 패턴을 찾고 있습니다. –

+2

C# 4.0에는 하나 이상의 인수를 포함 할 수있는 튜플이 있습니다. 이 질문에 대한 내 대답을 참조하십시오. –

4

대신 입력 된 개체입니다. C# 4.0에서는 튜플을 제공합니다. 튜플을 사용하여 여러 args를 보유 할 수 있습니다. 그렇다면 새로운 클래스를 선언 할 필요가 없습니다.

1

이 작동하는 방법에 정교한 수있는 모든 인수

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; 
} 
관련 문제