2010-09-22 2 views
16

Я написал пример консольного приложения для тестирования фонового рабочего, используя один из примеров, размещенных здесь в Stackoverflow. У меня есть работник backgroundwork, который начинается с основного метода, но заканчивается в середине операции, если я нажимаю кнопку ввода, потому что я написал файл console.readkey в основном методе. Но я хочу, чтобы он подождал, пока фоновая работа закончит выполнение задания, а затем выйдет из приложения. Это мой код.Как подождать, когда BackgroundWorker закончит, а затем выйдет из консольного приложения

class Program 
{ 
    private static BackgroundWorker worker = new BackgroundWorker(); 
    private event EventHandler BackgroundWorkFinished; 

    static void Main(string[] args) 
    { 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     worker.ProgressChanged += worker_ProgressChanged; 
     worker.WorkerReportsProgress = true; 
     worker.WorkerSupportsCancellation = true; 

     Console.WriteLine("Starting Application..."); 

     worker.RunWorkerAsync(); 
     Console.ReadKey(); 
    } 

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Console.WriteLine("Starting to do some work now..."); 
     int i; 
     for (i = 1; i < 10; i++) 
     { 
      Thread.Sleep(1000); 
      worker.ReportProgress(Convert.ToInt32((100.0 * i)/10)); 
     } 

     e.Result = i; 
    } 

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("Value Of i = " + e.Result.ToString()); 
     Console.WriteLine("Done now..."); 
    } 
} 
+1

Почему вы запустили фоновый процесс Async? Кажется, вы хотите, чтобы он запускался синхронно ... –

+1

Как запустить его синхронно .. ??? –

+0

Возможный дубликат [Как подождать, когда BackgroundWorker отменит?] (Http://stackoverflow.com/questions/123661/how-to-wait-for-a-backgroundworker-to-cancel) –

ответ

8

См. Сообщение How to wait for a BackgroundWorker to cancel?, чтобы узнать, как установить связь между BackgroundWorker и основной темой.

В принципе, вы должны использовать событие, которое вы установили в конце DoWork, чтобы сигнализировать о завершении DoWork. Затем вы вызываете WaitOne() на этом событии в своем основном потоке.

+0

Я добавил новый код в качестве ответа. Но есть еще проблема. Пожалуйста помоги. –

4

Основная цель Bgw - взаимодействовать с Windows MessageQueue. Другими словами, это наиболее полезно в WinForms и WPF-приложениях.

Консольное приложение не подходит для использования или тестирования Bgw. Вы получите странные результаты. Распечатайте ManagedThreadId в ключевых точках, чтобы узнать, что произойдет.

И некоторый стандартный совет: Ваш worker_RunWorkerCompleted() должен проверить e.Error. Теперь это то же самое, что и пустой блок catch{}.
Любая ошибка DoWork теперь будет брошена, когда вы будете читать e.Result, более сложную для обработки.

2

Это то, что я сделал сейчас. Но console.readkey() не работает. Приложение не ждет функции ReadKey().

class Program 
{ 
    private static BackgroundWorker worker = new System.ComponentModel.BackgroundWorker(); 
    private static AutoResetEvent resetEvent = new AutoResetEvent(false); 
    static void Main(string[] args) 
    { 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     worker.ProgressChanged += worker_ProgressChanged; 
     worker.WorkerReportsProgress = true; 

     Console.WriteLine("Starting Application..."); 

     worker.RunWorkerAsync(); 
     resetEvent.WaitOne(); 

     Console.ReadKey(); 
    } 

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Console.WriteLine("Starting to do some work now..."); 
     int i; 
     for (i = 1; i < 10; i++) 
     { 
      Thread.Sleep(1000); 
      worker.ReportProgress(Convert.ToInt32((100.0 * i)/10)); 
     } 

     e.Result = i; 

     resetEvent.Set(); 
    } 

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("Value Of i = " + e.Result.ToString()); 
     Console.WriteLine("Done now..."); 
    } 

} 

Закрепление Edit: Переехал resetEvent.Set() внутрь DoWork, а не в RunWorkerCompleted. Обработчик события Завершено никогда не будет вызван, потому что главный поток ждет события.

+0

Если я использую этот код в проекте консоли в VS2008 с .NET 3.5 SP1 в Windows 7, он работает для меня. –

+0

Не работает для меня в VS2008 в Windows XP. –

+0

Пожалуйста, помогите .... –