2011-01-26 5 views
115

Предположим, я хочу отправить параметр int второму работнику, как это можно сделать?Отправка аргументов фонового работника?

private void worker_DoWork(object sender, DoWorkEventArgs e) { 

} 

Я знаю, когда это worker.RunWorkerAsync() ;, я не понимаю, как определить в worker_DoWork, что он должен принимать параметр Int.

ответ

192

Вы начинаете так:

int value = 123; 
bgw1.RunWorkerAsync(value); // argument: value, the int will be boxed 

, а затем

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    int value = (int) e.Argument; // the 'argument' parameter resurfaces here 

    ... 

    // and to transport a result back to the main thread 
    double result = 0.1 * value; 
    e.Result = result; 
} 


// the Completed handler should follow this pattern 
// for Error and (optionally) Cancellation handling 
private void worker_Completed(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // check error, check cancel, then use result 
    if (e.Error != null) 
    { 
    // handle the error 
    } 
    else if (e.Cancelled) 
    { 
    // handle cancellation 
    } 
    else 
    {   
     double result = (double) e.Result; 
     // use it on the UI thread 
    } 
    // general cleanup code, runs when there was an error or not. 
} 
+27

Как я могу сделать два аргумента ? – sooprise

+3

Или я посылаю объект, полный нескольких аргументов? – sooprise

+19

@soo: Используйте вспомогательный класс или 'Tuple ' (C# 4 +) (Edit: Да, используйте объект, чтобы упаковать все это. См. Например, DoWorkEventArgs self). –

9

Вы можете использовать собственность DoWorkEventArgs.Argument.

Полный пример (даже с помощью Int аргумент) можно найти на сайте Microsoft:

5

Отъезд DoWorkEventArgs.Argument Property:

... 
backgroundWorker1.RunWorkerAsync(yourInt); 
... 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Do not access the form's BackgroundWorker reference directly. 
    // Instead, use the reference provided by the sender parameter. 
    BackgroundWorker bw = sender as BackgroundWorker; 

    // Extract the argument. 
    int arg = (int)e.Argument; 

    // Start the time-consuming operation. 
    e.Result = TimeConsumingOperation(bw, arg); 

    // If the operation was canceled by the user, 
    // set the DoWorkEventArgs.Cancel property to true. 
    if (bw.CancellationPending) 
    { 
     e.Cancel = true; 
    } 
} 
83

Несмотря на это уже ответил вопрос, я оставил бы другой вариант, который ИМО намного легче читать:

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += (obj, e) => WorkerDoWork(value, text); 
worker.RunWorkerAsync(); 

И на методе обработчика :

private void WorkerDoWork(int value, string text) { 
    ... 
} 
+8

Я не знал, что означает ИМО, я думал, что это C#. Я googled «C# IMO» и приземлился здесь и получил ответ ... lol https://www.quantnet.com/threads/c-c-vba-or-java.11433/ – electricalbah

+0

Как насчет 3 параметров? – YukiSakura

+0

Я не играю с .NET с 2012 года, но если я не ошибаюсь, вы можете добавить нужные параметры '... => WorkerDoWork (a, b, c);', если он соответствует сигнатуре метода '... WorkerDoWork (int a, string b, string c) {...' – dcarneiro

36

Вы можете передать несколько таких аргументов.

List<object> arguments = new List<object>(); 
        arguments.Add(argument 1); 
        arguments.Add(argument 1); 
        arguments.Add(argument n); 


        backgroundWorker2.RunWorkerAsync(arguments); 

private void worker_DoWork(object sender, DoWorkEventArgs e) { 

    List<object> genericlist = e.Argument as List<object>; 
    extract your multiple arguments from this list and cast them and use them. 

} 
+1

как извлечь несколько аргументов из кода выше, пожалуйста, помогите .. – missReclusive

+0

@missReclusive лидирует «общий список», элементы, т. е. Пусть say «аргумент 1» имеет тип int, тогда int argument1 = (int) genericlist [0] –

+1

это плохая идея с точки зрения обслуживания. Вы должны использовать конкретные типы над списком , потому что по крайней мере вы сможете выяснить, что вы делали (см. Пример в моем ответе ниже) – Denis

4

вы можете попробовать это, если вы хотите передать более чем один тип аргументов, первый добавьте их в массив типа Object и передать этот объект в RunWorkerAsync() вот пример:

some_Method(){ 
    List<string> excludeList = new List<string>(); // list of strings 
    string newPath ="some path"; // normal string 
    Object[] args = {newPath,excludeList }; 
      backgroundAnalyzer.RunWorkerAsync(args); 
     } 

Теперь в методе DoWork фоновых рабочего

backgroundAnalyzer_DoWork(object sender, DoWorkEventArgs e) 
     { 
     backgroundAnalyzer.ReportProgress(50); 
     Object[] arg = e.Argument as Object[]; 
     string path= (string)arg[0]; 
     List<string> lst = (List<string>) arg[1]; 
     ....... 
     // do something...... 
     //..... 
     } 
+0

+1. Отправка аргументов таким образом также позволяет избежать запуска нового рабочего стола, чтобы избежать повторений. (по крайней мере, в моем приложении). См. Мой комментарий ниже, связанный с этой проблемой. Также http://stackoverflow.com/a/12231431/503621 & http://stackoverflow.com/questions/12507602/c-sharp-backgroundworker-keep-on-running-dowork – bshea

4

Вы всегда должны пытаться использовать композитный объект с конкретными типами (с использованием композитного шаблона проектирования), а не список объектов типы. Кто бы мог вспомнить, что такое каждый из этих объектов? Подумайте о поддержании кода позже ... Вместо этого, попробовать что-то вроде этого:

Public (Class or Structure) MyPerson 
       public string FirstName { get; set; } 
       public string LastName { get; set; } 
       public string Address { get; set; } 
       public int ZipCode { get; set; } 
End Class 

И потом:

Dim person as new MyPerson With { .FirstName = “Joe”, 
            .LastName = "Smith”, 
            ... 
           } 
backgroundWorker1.RunWorkerAsync(person) 

, а затем:

private void backgroundWorker1_DoWork (object sender, DoWorkEventArgs e) 
{ 
     MyPerson person = e.Argument as MyPerson 
     string firstname = person.FirstName; 
     string lastname = person.LastName; 
     int zipcode = person.ZipCode;         
} 
Смежные вопросы