2017-08-07 14 views
1

私はAccessデータベースからいくつかのレコードを抽出するC#でコードを作成しますが、ボタンのクリックに依存して次の繰り返しに行く必要があります。私はいくつかのスレッドやタスクを試しましたが、私はそれを見てクリック可能にする必要があるUIをブロックしたので、うまくいきませんでした。ボタンが押されるまで無限ループのようにUIを作成する

bool nextClick = false ; 

       while (readerSelect.Read()) 
       { 

        // show the correct panel 
        if (string.Compare(readerSelect[2].ToString(), "P1") == 0) 
        { 
         // panel with type 1 
         textBoxP1Text1.Text = readerSelect[3].ToString(); 
         textBoxP1Text2.Text = readerSelect[4].ToString(); 
         pictureBoxP1Image.ImageLocation = readerSelect[6].ToString(); 

        } 
        else 
        { 
         // panel with type 2 
         textBoxP1Text2.Text = readerSelect[5].ToString(); 
        } 

    //this while need to be kind of infinite so the interation can't be processed and 
    //so when i need to change iteration i click the buttonNext 
        while (!nextClick) { 
        startWhile:; 
         MethodInvoker mi = delegate() { 
          if (nextClick) 
          { 
           Application.DoEvents(); 
           // System.Windows.Forms.Application.Run(); 
          } 

         }; 
         this.Invoke(mi); 
         //break; 
         goto startWhile; 
        } 

private void buttonNext_Click(object sender, EventArgs e) 
    { 
     // click on the next button 
     nextClick = true; 
    } 
+1

クリック後に次の項目に移動する必要がある場合は、whileループを使用しないでください。各クリックで1つだけを実行してください。 – Milney

+0

これは、私たちの接続に大きな影響を与えます貧しいですが、お返事ありがとうございます –

+0

「あなたの接続に大きな影響を与える」とはどういう意味ですか?それはちょうど間違っている。あなたが今やってやっているやり方は、そこにたくさんの記録があることだけを読むことになります。あなたは間違っています。あなたが最初のポイントとしてそれをよりよく理解するまで、DataReaderドキュメントを読むことをお勧めします。 – Milney

答えて

2

、それはそうです。あなたはSingle Responsibility Principleに違反していると思いますが、あまりにも多くのビジネスロジックがFormクラスで行われています。

ビジネスロジックを独自のクラスに分解することをお勧めします。ループ内のすべてを実行するのではなく、単にボタンクリックイベントを次のレコードに処理させ、結果を表示させるだけです。ここに私が意味するものの例があります:

public partial class Form1 : Form 
{ 
    private readonly DataProcessor dataProcessor = new DataProcessor(); 

    public Form1() 
    { 
     this.InitializeComponent(); 
    } 

    private void button1Next_Click(object sender, EventArgs e) 
    { 
     this.buttonNext.Enabled = false; 
     this.ProcessNext(); 
    } 

    private async void ProcessNext() 
    { 
     string s = await this.dataProcessor.ProcessNext(); 
     this.textBoxP1Text1.Text = s; 
     this.buttonNext.Enabled = true; 
    } 
} 

public class DataProcessor 
{ 
    private readonly Random r = new Random(); // Or reader or whatever. 

    public async Task<string> ProcessNext() // Just using `string` as an example. 
    { 
     await Task.Delay(1000); 
     return this.r.Next().ToString(); 
    } 
} 

これは理解しやすく、将来的にはより保守的になると思います。新しいチームメンバーがセマフォーのもの(またはあなたの将来の自己)を見ると、それが何であったかを理解したり覚えたりするのは難しいでしょう。ここでは、1つのことを行い、それに従うのは簡単なローカル関数があります。

3

あなたは非同期タスク内でセマフォを使用することができますが、通じそれを毎回待つ各クリック時にボタンReleaseそれを持って、whileループを持っている:

は、ここでは、コードです。ここbutton1と、それに追加label1を持つフォームを使用して、簡単な例です:ダックスFohlの答えは動作しますが、あなたのデザインの問題を持っているよう

public partial class Form1 : Form 
{ 
    private readonly SemaphoreSlim signal = new SemaphoreSlim(0, int.MaxValue); 

    public Form1() 
    { 
     this.InitializeComponent(); 
     this.RunLoop(); 
    } 

    private async void RunLoop() 
    { 
     var i = 0; 
     while (true) 
     { 
      this.label2.Text = $"Enqueued: {this.signal.CurrentCount}"; 
      await this.signal.WaitAsync(); // Wait button click async 
      await Task.Delay(1000); // Simulate work 
      this.label1.Text = $"Completed: {++i}"; 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     this.signal.Release(); 
     this.label2.Text = $"Enqueued: {this.signal.CurrentCount + 1}"; 
     // Or if you want to limit the # people can queue up, then put this whole 
     // thing in an `if (signal.CurrentCount < myLimit)` block, and optionally 
     // disable the button once limit has been reached, and re-enable it right 
     // before the `WaitAsync` call above. 
    } 
} 
+0

実行ループが完了している間にユーザーが複数回クリックすると、SemaphoreFullExceptionが発生する可能性がありますか?私はEventWaitHandleクラスの1つがより適切であると思っていたでしょう。 –

+0

@MartinBrownはい、ちょうどそれのためのアカウントの答えを更新しました。 –

+0

ありがとう、それは私のために働いた:) –

関連する問題