2013-08-12 51 views
5

私の問題は、しばらく解決策を探していましたが、成功しませんでした。別のスレッドで作成されたフォームを閉じる

私のプログラムには数秒かかるタスクがあり、そのタスクが完了している間に新しいフォームを表示したいのですが。新しいフォームにはローディングバーとテキストがあります。

新しいフォームをタスクと並行して表示する必要があります。そうしないと、新しいフォームを閉じるまでタスクが開始されません。

これは私が今持っているソリューションです。

private void loadingBar() 
{ 
    frmLoading frm = new frmLoading("Please wait while the database is being backed up", "This might take several days."); 
    frm.ShowDialog(); 

} 

public void Backup() 
{ 
    Thread load = new Thread(new ThreadStart(loadingBar)); 
    load.Start(); 

    ///Execute a task. 

    load.Abort(); 
} 

だから、これはOKに動作しますが、私の質問です:作るために、負荷のスレッドでフォーム「FRM」を閉鎖するほうがよいのではないだろうそれは止まる?

+1

プログレスバーのように扱います。表示するフォームに従属するバックグラウンドスレッドとして「プロセス」を実行します。その後、そのフォームを「メイン」スレッドから呼び出します。メインスレッドは読み込みフォームを表示してロックし、読み込みフォームはバックグラウンドスレッドとして何かを実行します。こうすることで、読み込みフォーム自体がプロセスを追跡し、一旦終了するとそのプロセスを終了することができます。 – Nevyn

+3

@Daveなぜ 'backgroundWorker'を使わないのですか? また、スレッドのコードを 'Using()'ステートメントに入れることを検討すると、完了時にスレッド自体が破棄されます。 – Hexie

+1

これは基本的には間違ったことです。ワーカースレッドにUIを表示するには、いくつかの非常に厄介な失敗モードがあります。これを逆にする必要があり、UIスレッドに「読み込み中」ウィンドウを表示し、ワーカースレッド上でバックアップを実行します。 –

答えて

1

クラスレベルでフォームを宣言し、後でそれを呼び出して閉じることができます。あなたは

準備ができたらfrmCloseあなたがBendEgが示唆されているように行うと呼び出すことができます - あなたはこのにはいくつかの方法...

1を行うことができ

public class Class1 
{ 
    private Form myForm; 

    public Class1() 
    { 
     myForm = new Form(); 
    } 

    public void DoSomeWork() 
    { 
     // =================================================== 
     // Do Some Work... 
     // =================================================== 

     myForm.Invoke(new MethodInvoker(this.Hide)); 
    } 

    public void Hide() 
    { 
     myForm.Hide(); 
    } 

    public void Backup() 
    { 
     myForm.ShowDialog(); 

     Thread load = new Thread(new ThreadStart(DoSomeWork)); 
     load.Start(); 
    } 
} 
2

:このように MSDN-Windows Forms Invoke

何かのようなもの;

Invoke(new Action(Close)); 

または

Invoke(new Action(() => frmMain.Close())); 

2 - それとも、単にバックグラウンドワーカーを使用することができます。

これを実証する最も簡単な方法は、フォームにBackgroundWorkerを追加し、提供されたイベントを使用することです。

public Form1() 
{ 
    InitializeComponent(); 
    backgroundWorker1.RunWorkerAsync(); 

    MessageBox.Show(@"Please wait while the database is being backed up", @"This might take several days."); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Debug.WriteLine("Running"); //Execute a task 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    Debug.WriteLine("Ended"); //Dispose of any objects you'd like (close yor form etc.) 
} 

これが役立ちます。

0

私は(私は右のあなたを理解している場合)、これはあなたを助けるだろうと思う:

   Parallel.Invoke(() => somemethod(),() => 
       { 
        someothertaskmethod(); 
       }); 

私が実行している2つのタスクを実証する例の方法を配置。

あなたは、私はこれがあなたのために働くことができると思う適切なusingステートメントusing System.Threading.Tasks;

1

を使用することを旧姓。

void YourMethod() 
{ 
    WaitForm wf = new WaitForm(); 
    Invoke(new PleaseWaitDelegate(Launch),wf); 
    bool val = BoolMethodDoWork(); 
    Invoke(new PleaseWaitDelegate(Close), wf); 
       if(val) 
       { 
        MessageBox.Show("Success!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
        return; 
       } 
       MessageBox.Show("Damn!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
} 
delegate void PleaseWaitDelegate(Form form); 
     void Launch(Form form) 
     { 
      new System.Threading.Thread(()=> form. ShowDialog()).Start(); 
     } 

     void Close(Form form) 
     { 
      form.Close(); 
     } 
関連する問題