2010-08-13 5 views
2

Dans le code ci-dessous, est-il un moyen de au lieu de toujours vous inscrivant la méthode updateWorker_DoWork, passer une méthode comme celui-ciLe passage d'une méthode à un DoWork BackgroundWorker

public void GetUpdates(SomeObject blah) 
{ 
    //... 
    updateWorker.DoWork += new DoWorkEventHandler(blah); 
    //... 
} 


public void GetUpdates() 
{ 
    //Set up worker 
    updateWorker.WorkerReportsProgress = true; 
    updateWorker.WorkerSupportsCancellation = true; 
    updateWorker.DoWork += new DoWorkEventHandler(updateWorker_DoWork); 
    updateWorker.RunWorkerCompleted += 
     new RunWorkerCompletedEventHandler(updateWorker_RunWorkerCompleted); 
    updateWorker.ProgressChanged += 
     new ProgressChangedEventHandler(updateWorker_ProgressChanged); 

    //Run worker 
    _canCancelWorker = true; 
    updateWorker.RunWorkerAsync(); 
    //Initial Progress zero percent event 
    _thes.UpdateProgress(0); 
} 

Répondre

2

Si je ne vous ai pas mal compris, vous besoin d'expressions lambda pour construire une méthode anonyme.

updateWorker.DoWork += (sender,e)=> 
    { 
     //bla 
    } 

Maintenant, vous ne devez pas toujours d'écrire une méthode et le transmettre à new DoWorkEventHandler(myMethod)

2

Pour votre RunWorkerAsync() vous pouvez passer un argument que vous voulez. Vous pouvez simplement y mettre un Func() ou Action() et dans votre DoWork() vous venez de renvoyer l'objet à ce type spécifique et de l'appeler. Les exemples sont les suivants: here et here.

private void InitializeBackgroundWorker() 
{ 
    _Worker = new BackgroundWorker(); 

    // On a call cast the e.Argument to a Func<TResult> and call it... 
    // Take the result from it and put it into e.Result 
    _Worker.DoWork += (sender, e) => e.Result = ((Func<string>)e.Argument)(); 

    // Take the e.Result and print it out 
    // (cause we will always call a Func<string> the e.Result must always be a string) 
    _Worker.RunWorkerCompleted += (sender, e) => 
    { 
     Debug.Print((string)e.Result); 
    }; 
} 

private void StartTheWorker() 
{ 
    int someValue = 42; 

    //Take a method with a parameter and put it into another func with no parameter 
    //This is called currying or binding 
    StartTheWorker(new Func<string>(() => DoSomething(someValue))); 

    while(_Worker.IsBusy) 
     Thread.Sleep(1); 

    //If your function exactly matches, just put it into the argument. 
    StartTheWorker(AnotherTask); 
} 

private void StartTheWorker(Func<string> func) 
{ 
    _Worker.RunWorkerAsync(func); 
} 

private string DoSomething(int value) 
{ 
    return value.ToString("x"); 
} 

private string AnotherTask() 
{ 
    return "Hello World"; 
} 
+0

Merci. Donc quel serait le type d'argument si je voulais passer le délégué dans la fonction StartTheWorker. Essentiellement, je veux être en mesure d'appeler StartTheWorker (DoSomething) et avoir DoSomething fonctionner comme un travailleur de fond – James

+0

@James: C'est juste un autre wrapper à construire avec 'Func()'. J'ai mis à jour l'exemple pour refléter cela. – Oliver

1

avaient calculé ce, était beaucoup plus simple que ce que je pensais. Juste dû faire un délégué pour la méthode appelée sur DoWork. Probablement aurait dû mieux formuler ma question initiale.

public delegate void DoWorkDelegate(object sender,DoWorkEventArgs e); 

    public void GetUpdates() 
    { 
     StartWorker(new DoWorkDelegate(updateWorker_DoWork)); 
    } 

    public void StartWorker(DoWorkDelegate task) 
    { 
     //Set up worker 
     updateWorker.WorkerReportsProgress = true; 
     updateWorker.WorkerSupportsCancellation = true; 
     updateWorker.DoWork += new DoWorkEventHandler(task); 
     updateWorker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(updateWorker_RunWorkerCompleted); 
     updateWorker.ProgressChanged += 
      new ProgressChangedEventHandler(updateWorker_ProgressChanged); 

     //Run worker 
     _canCancelWorker = true; 
     updateWorker.RunWorkerAsync(); 
     //Initial Progress zero percent event 
     _thes.UpdateProgress(0); 
    } 

     private void updateWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      e.Result = GetUpdatesTask(worker, e); 
     } 
Questions connexes