2010-11-26 9 views
0

私は、私のUIフォームで開始と停止の2つのボタンを持っています。私はメソッドのクラス名プログラムでいくつかの機能を実行する無限ループを1つ持っています。ユーザーはこのメソッドを呼び出して無限ループを実行し、ユーザーが停止ボタンをクリックするとこの無限ループを解除する必要があります。その後、この無限ループからブレークしてボタン停止クリック内のコードに入ります。 Application.DoEvents()メソッドを使用しようとしていますが、無限ループコードがスタートボタンのクリックの内側にある場合はうまくいきますが、無限ループコードが私のプログラムで作成された新しいクラスにある場合、 Application.DoEvents()この無限ループから脱出する方法。私の無限ループを中断する

例:

namespace inFiniteLoopTest 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     bool stopBtnClk = false; 
     bool startBtnClk = false; 

     private void StartBtn_Click(object sender, EventArgs e) 
     { 
      stopBtnClk=false; 

      startBtnClk = true; 

      while(true) 
      { 
       //some code to be executed 
       Application.DoEvents(); 
       if (stopBtnClk == true) 
       { 
        break; 
       } 
      } 
     } 

     private void StopBtn_Click(object sender, EventArgs e) 
     { 
      stopBtnClk = true; 
      if (startBtnClk == true) 
      { 
       //Application.Exit(); 
       MessageBox.Show("success"); 

      } 

     } 

これがうまく機能しています。

しかし

public class programs 
{  
    public static void infiniteLoop(bool stopBtnClick) 
    {  
     while(true) 
     { 
      //some code to be executed 
      Application.DoEvents(); 
      if (stopBtnClk == true) 
      { 
       break; 
      } 
     } 
    }  
} 

//and my UI code to call this class is 
namespace inFiniteLoopTest 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     bool stopBtnClk = false; 
     bool startBtnClk = false; 

     private void StartBtn_Click(object sender, EventArgs e) 
     { 
      stopBtnClk=false;  
      startBtnClk = true; 
      programs.infiniteLoop(stopBtnClk); 
     } 

     private void StopBtn_Click(object sender, EventArgs e) 
     { 
      stopBtnClk = true; 
      if (startBtnClk == true) 
      { 
       //Application.Exit(); 
       MessageBox.Show("success"); 
      } 
     }    
    } 

が、これは動作しません。

停止ボタンがクリックされたときにコンパイラが「成功」というメッセージを表示したにもかかわらず、デバッガがまだ自分のフォームで実行していると言っても。 私の質問がはっきりしていることを願っています。 そして、私はあなたに私の質問にできるだけ早く答えて、この問題を取り除くようお願いしています。 特にスレッドに参加した場合、私は公然と答えを受け入れます。

私はC#の初心者ですが、私はそれを続ける必要があります。

ありがとうございました!

+2

なぜこの質問がC#にのみ関連するのであれば、[Java]、[PHP]、[C++]、および[C] (私は適切なタグだけを含むように編集しました)。 –

+0

コードを再フォーマットしてください。ブロック全体を選択し、その上に「コードサンプル」機能を使用するか、2回実行する必要があるかもしれませんが、最終的にどのように見えるかのプレビューも表示されます。 – Mephane

+0

作業を行うにはスレッドを使用する必要があります。 – MrFox

答えて

0

あなたが提供したコードを読み、本当に難しいですが、限り、あなたの無限ループを作成するときに、私が見ることができるようにしてください:あなたが押したときwhile(looping) // do stuff

は、[停止]ボタンをfalseにループブール変数を設定し、それループから抜け出してメッセージを表示します。

+0

コンパイラが開始ボタンによって無限ループを取得すると、そのループから抜け出せません。クリックすると、アクション/イベント(停止ボタンのクリック)は考慮されません。これは私の問題です。ボタンがクリックされたときにそのイベントを処理するためのトリックが必要です。特にスレッドを使用しています。 – Gir

+0

ありがとうございます!!!!!!!!!! – Gir

0

なぜ無限ループの代わりに、ボタンによって決定される開始停止条件を使用しますか?

私はちょうどあなたが最初のボタン(スタート)をクリックしたときに、それがどこに今、あなたは(メソッドを呼び出す

bool stop_loop = false 

とあなたのループ

while(!stop_loop){ //CODE HERE } 

それを呼び出す、あなたは変数を持つことができます考えて)ループを開始します。ボタンストップをクリックしてstop_loopの値がTrueになるまで、ループは無限に見えます。

HTH

+0

@ SubniC:たとえ私がそれを作ったとしても、ストップボタンクリックのイベントを考慮していません。 – Gir

+0

@サブクォーンあなたはあなたのブール宣言にvolatileを加える必要があると思います。 –

+0

@وليدتاجالدين揮発性キーワードを使用してください... –

7

GUIスレッドをブロックしないでください。 GUIを更新するためにApplication.DoEvents()を使用しなければならないという事実は、悪い設計の指標です。別のワーカースレッドで作業を行います。

BackgroundWorkerは、このようなタスクのために予定されています。このようなあなたのinfiniteLoop方法の

+1

この回答には十分な矢印がありません。 –

0

変更署名:2番目のコードスニペットで

public static void infiniteLoop(ref bool stopBtnClick) ...

+0

スタートボタンクリックの中のメソッドはどうでしょうか?それはprograms.infiniteLoop(stopBtnClk)です。この関数を呼び出す。 エラー引数 '1'は 'ref'キーワードで渡されなければなりません – Gir

+0

このようにrefで渡します: programs.infiniteLoop(ref stopBtnClk); –

0

、無限ループをパラメータとしてブール値を受け入れるサブルーチンで開始されました。サブルーチンは、どのようにしてそのブール値をもう一度見てみましょうか?その値を一度しか見ることはできず、その時は偽です。それはスコープの問題です。

+0

私はそれがイベントハンドラメソッドApplication.DoEvents()にあると思います。 しかし、間違っているかもしれませんが、私は停止ボタンをクリックすると "成功"というメッセージが表示されますが、その理由は私のフォームが私がまだ実行中であることを示しています。しかし、言葉も。 – Gir

関連する問題