none
新たに作ったフォームをクローズすると、アプリケーションが終了する。 RRS feed

  • 質問

  • 以下のようなform1がらスタートするアプリケーションを作成しています。

    CLASS_Aは、CLASS_Bで起動するプロセスの詳細の設定が集まっているものとします。

    で、タイマで設定した時間後、b。関数()を実行して、formBを表示します。

    あたらしいプロセスが終了したイベントで、そのformBを消したとたんに、アプリケーションが終了してしまいます。

    なぜ、そうなるのか、わかりません。

    私は、何か間違いを犯していたり、何かし足りなかったリしているのでしょうか?

    class form1{
       class CLASS_A a;
    }

    class CLASS_A {
       CLASS_B b = new CLASS_B;
       Timer タイマ:
       タイマ完了(){  b.関数();   }
    }

    class CLASS_B{
       NewProcess np;
       Form formB;

       関数(){ formB=new Form();   formB.show();  np.Start(); }
       np_終了イベント関数(){   formB.close();  }

    }

     

    2010年10月8日 4:11

回答

  • >新しいプロセスとは、コンソールアプリーケーションです。

     

    失礼しました。では、恐らくプロセスで生成された新しいスレッドからプロセス終了の

    イベントが発生するため、単純に別スレッドからフォームのUIスレッドを操作しようと

    しているために発生していると思います。

     

    ひょっとして、このClass Bが、別ファイルとかは、関係ないですよね?

    関係ないと思います。


    以下のように変更してみてください。

    // ご提示のコード
    private void Endrec(object sender, System.EventArgs e)
    {
      is_rec = false;
      form2.Close();
    }
    
    // 変更後のコード
    private delegate void CloseDelegate();
    private void Endrec(object sender, System.EventArgs e)
    {
      is_rec = false;
      form2.Invoke(new CloseDelegate(form2.Close));
    }
    
    

    2010年10月8日 7:22

すべての返信

  • ご提示されているコードと説明文ではちょっとわからない部分がありましたので、質問ですが、

    「あたらしいプロセス」とは、新しいスレッドという解釈でよろしいですか?

    また、

    そのformBを消したとたんに、アプリケーションが終了してしまいます。

     

    とありますが、本当にそこまでたどり着いていますか?

    それ以前の別スレッド内部などで例外が発生していませんか?


    私なりの解釈ではありますが、ご説明内容通りに以下のようにコードを組んでみましたけど、

    特にそういった現象は発生しませんでした。

     

    /// <summary>Form1クラス</summary>
    public partial class Form1 : Form
    {
    	public Form1()
    	{
    		InitializeComponent();
    	}
    
    	/// <summary>処理開始</summary>
    	private void button1_Click(object sender, EventArgs e)
    	{
    		CLASS_A clsA = new CLASS_A();
    	}
    }
    /// <summary>クラスA</summary>
    public class CLASS_A
    {
    	private Timer tim = new Timer();
    	private CLASS_B clsB = null;
    	public CLASS_A()
    	{
    		clsB = new CLASS_B();
    		tim.Tick += new System.EventHandler(this.tim_Tick);
    		tim.Start();
    	}
    	private void tim_Tick(object sender, EventArgs e)
    	{
    		clsB.From2Show();
    		tim.Stop();
    	}
    }
    /// <summary>クラスB</summary>
    public class CLASS_B
    {
    	Form2 f = null;
    	private BackgroundWorker bgw = new BackgroundWorker();
    	public CLASS_B()
    	{
    		bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgw_Run);
    	}
    	public void From2Show()
    	{
    		f = new Form2();
    		f.Show();
    		System.Threading.Thread.Sleep(1000);
    		bgw.RunWorkerAsync();
    	}
    	private void bgw_Run(object sender, RunWorkerCompletedEventArgs e)
    	{
    		f.Close();
    	}
    }
    
    

     

    2010年10月8日 4:53
  • お返事ありがとうございます。

    新しいプロセスとは、

                newProcess = new Process();
    として作成したプロセスで、コンソールアプリーケーションです。それは、時間が来ると終了するもので、

                newProcess.Exited += new EventHandler(Endrec);
    で、終了したときに、

            private void Endrec(object sender, System.EventArgs e)
            {
                is_rec = false;
                form2.Close();
            }
    が、呼ばれます。

    このform2.close()を実行すると、アプリケーションが終わってしまうのです。

    ちなみに、form2の×ボタンを押しても、アプリは終わりません。

    ひょっとして、このClass Bが、別ファイルとかは、関係ないですよね?

    2010年10月8日 7:02
  • >新しいプロセスとは、コンソールアプリーケーションです。

     

    失礼しました。では、恐らくプロセスで生成された新しいスレッドからプロセス終了の

    イベントが発生するため、単純に別スレッドからフォームのUIスレッドを操作しようと

    しているために発生していると思います。

     

    ひょっとして、このClass Bが、別ファイルとかは、関係ないですよね?

    関係ないと思います。


    以下のように変更してみてください。

    // ご提示のコード
    private void Endrec(object sender, System.EventArgs e)
    {
      is_rec = false;
      form2.Close();
    }
    
    // 変更後のコード
    private delegate void CloseDelegate();
    private void Endrec(object sender, System.EventArgs e)
    {
      is_rec = false;
      form2.Invoke(new CloseDelegate(form2.Close));
    }
    
    

    2010年10月8日 7:22
  • bool型の変数がいじれているから、すっかり普通に操作できるものと思っていました。

    delegateや、Invokeについても改めて勉強してみます。

    このたびは、ありがとうございました。

    2010年10月8日 8:27