2013-10-04 2 views
2

Я пытаюсь показать другую форму по основной форме в отдельном потоке на кнопку мыши с помощью фона рабочего потока, используя следующий код:Показать другую форму по основной форме в отдельном потоке

private void simpleButton1_Click(object sender, EventArgs e) 
    { 
     //this.Opacity = 50.5; 
     bw.RunWorkerAsync();      
     GetData(); 
     bw.CancelAsync(); 

    } 

    private void GetData() 
    { 
     for (int i = 0; i < 500000; i++) 
     { 
      datatable.Rows.Add(new object[] { "raj", "raj", "raj", i }); 
     } 
    } 

    void bw_DoWork(object sender,DoWorkEventArgs e) 
    { 

     XtraForm1 frm = new XtraForm1(); 
     while (!bw.CancellationPending) 
     { 
      frm.ShowDialog(); 
      frm.BringToFront(); 
      continue; 
     } 
     e.Cancel = true; 
    } 

Но проблема в том, что, когда я нажмите на основную форму, другая форма, запущенная в отдельном потоке, будет скрыта. Как я могу сделать это видимым до тех пор, пока основной поток не завершит выполнение, а затем удалит его?

+2

Почему вы хотите создать элемент пользовательского интерфейса в потоке, а не в потоке пользовательского интерфейса? –

+0

Используйте диалог Modal .. не это ..:/ –

+0

Я хочу показать что-то вроде экрана всплеска, показывая ожидающий текст, когда основной поток занят в выполнении –

ответ

2

Вы должны сделать это наоборот. Переместите свою петлю на BackgroundWorker и сохраните содержимое пользовательского интерфейса (показывая свою вторую форму) в основном потоке. Затем используйте BackgroundWorkerReportProgress и RunWorkerCompleted и т. Д., Чтобы правильно отобразить/скрыть вашу дополнительную форму.

Он будет выглядеть примерно так: XtraForm1 frm = new XtraForm1();

private void simpleButton1_Click(object sender, EventArgs e) 
{ 
    bw.ReportsProgress = true; 
    bw.RunWorkerAsync();      
    frm.ShowDialog(); 
} 

private void GetData() 
{ 
    for (int i = 0; i < 500000; i++) 
    { 
     datatable.Rows.Add(new object[] { "raj", "raj", "raj", i }); 
     if(i%1000==0) bw.ReportProgress((int)((i/500000f)*100)); 
    } 
} 

void bw_DoWork(object sender,DoWorkEventArgs e) 
{ 
    GetData(); 
} 

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //update your secondary form's UI here. I'm supposing you have a ProgressBar 
    //on your form named 'pbr' (make that control public) 
    frm.pbr.Value = e.ProgressPercentage; 
}  

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    frm.Hide(); 
}  
+0

Я не могу сделать это, поскольку у меня нет операции в основной теме. поэтому не может делать все в фоновом рабочем потоке –

+0

@RajeevKumar Вы можете. Ваш фоновый поток может сообщать о прогрессе в потоке пользовательского интерфейса, пока он занят работой. –

3

Ответ просто: вы этого не делаете. Пользовательский интерфейс имеет один поток, чтобы делать все видимое взаимодействие с пользователем, и должно быть заданием пользовательского интерфейса, чтобы показать приятное «Рабочее ...» для вашего пользователя, прежде чем дать контроль над вашим работником. Как только рабочий закончится, окно можно закрыть.

Ваш «основной» (UI) поток никогда не должен быть «занят». Это заморозит ваше окно. Загрузите всю работу в фоновое задание и пропустите основной поток, ожидая завершения работы вашего работника. Ваш рабочий поток может быть занят бесконечным циклом, ваш пользовательский интерфейс все равно будет реагировать. Даже если ответ только «все еще работает, извините».

Смежные вопросы