2015-02-17 3 views
1

Может кто-нибудь объяснить, почему вызов Thread.Sleep от BackgroundWorker блокирует его выполнение. Invoke должен вызвать выполнение делегата в потоке пользовательского интерфейса, а фоновый поток должен продолжить выполнение. Но этого не происходит - почему?C# BackgroundWorker и Invoke

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     BackgroundWorker bgrw = new BackgroundWorker(); 
     bgrw.DoWork += new DoWorkEventHandler(bgrw_DoWork); 

     bgrw.RunWorkerAsync(); 
    } 

    void bgrw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Console.WriteLine(DateTime.Now); 
     this.Invoke(new Action(() => { Thread.Sleep(2000); })); //should be executed on the UI thread 
     Console.WriteLine(DateTime.Now); // This line is executed after 2 seconds 
    }  
} 
+2

«Invoke должен вызвать выполнение делегата в потоке пользовательского интерфейса» - да - «и фоновый поток должен продолжаться» - нет. Посмотрите определение для ['Invoke'] (https://msdn.microsoft.com/en-us/library/zyzhdc6b (v = vs.110) .aspx) и обратите внимание, что это возвращаемое значение - это то, что возвращал делегат. Он не может вернуть это значение вам, пока код не завершит выполнение. Блоки 'Invoke'. –

+0

Почему бы просто не вызвать Thread.Sleep() из потока пользовательского интерфейса сразу после того, как вы запустили Backgroundworker? –

+0

Прочитайте это http://stackoverflow.com/a/229558/4112271 –

ответ

6

Это довольно простое объяснение. Invoke - блокирующий вызов. Если вы хотите стоять в очереди на работу в цикле сообщений UI асинхронно, используйте BeginInvoke вместо:

Выполняет указанный делегат асинхронно на резьбе, что базовый дескриптор элемента элемента управления был создан.

void bgrw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Console.WriteLine(DateTime.Now); 
    this.BeginInvoke(new Action(() => { Thread.Sleep(2000); })); 
    Console.WriteLine(DateTime.Now); 
} 

Примечание код, как в настоящее время строится не имеет никакого смысла. Я предполагаю, что вы используете это для тестирования.