2016-09-27 16 views
-1

ファイルを分解してコンポーネントをサーバーに送信するWindowsフォームプログラムを作成しました。これらのファイルは大きく、progressBarを作成したので、トランザクションが発生している間にユーザーが凍っているとは思われませんでした。私がしたいのは、UIスレッドをブロックせずにすべてのスレッドが完了したときにのみアクティブになるようなメカニズムを持つことです(再度、プレブはフリーズしないと思うでしょう)。私が思いつくことができる最高のものは、一種の受動的な「真実まで待つ」ことですが、これを行うにはよりよい方法が必要であると感じています。私はイベントやコールバックを作成しようとしたことを実験しましたが、正直なところ、私が始めたときよりも混乱しました。 How to use a BackgroundWorker?進行状況バーの完了時にイベントをトリガーする方法

スレッドが

+3

あなたはプログレスバーに値を与えている人なので、100になったら、やりたいことの方法を呼んでください。まず、TaskFactoryは必要ありません。 –

+0

第3番 - そこには何本の線がありますか?メッセージボックスを表示するような処理は処理自体よりも時間がかかる –

+0

'ValueChanged'イベントをコーディングし、' Value == Maximum 'を確認することができます – TaW

答えて

1

を終了したとき、Microsoftのを使用してみてくださいためBackGroundWorker.RunWorkerCompleteを使用する:あなたが見る、BackgroundWorkerのクラスを使用する必要があります

public partial class Program : Form 
    { 
     private readonly OpenFileDialog _ofd = new OpenFileDialog(); 
     public delegate void BarDelegate(); 
     private string _path; 

     private void button1_Click(object sender, EventArgs e) 
     { 
      if (_ofd.ShowDialog() != DialogResult.OK) return; 

      textBox1.Text = _ofd.SafeFileName; 
      _path = _ofd.FileName; 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      var allLinesFromFile = File.ReadAllLines(_path); 
      progressBar1.Minimum = 0; 
      progressBar1.Maximum = allLinesFromFile.Length; 

      Task.Factory.StartNew(() => Parallel.ForEach(allLinesFromFile, DoSomething)); 

      while (progressBar1.Value < progressBar1.Maximum) //there has to be a better way to do this... 
      { 
       MessageBox.Show("Please wait.", "Record Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
      } 

      //some processes here which should only take place after all threads are complete. 

      var postingComplete = MessageBox.Show("The posting is complete!", "Record Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
      if (postingComplete == DialogResult.OK) Environment.Exit(0); 
     } 

     private void DoSomething(string record) 
     { 
      //some string manipulation and server transactions here 

      BeginInvoke(new BarDelegate(() => progressBar1.Increment(1))); 
     } 
    } 
+0

私は答えを感謝しますが、これはすべてのスレッドが完了する前にサブスクライブアクションを処理するように見えます。いくつかの計算は、すべてのスレッドが完了した後に行う必要があります。このソリューションでは、最後のスレッドが起動されたときに実際にサーバーに送信される前にサブスクリプションブロックが実行されます。大きなファイルでこれを実行すると、バーが終了する前に「投稿完了」というメッセージがポップアップ表示されるため、これを伝えることができます。これは、ThreadPoolにメソッド呼び出しを追加しようとしたときと同じ問題です。そのため、Parallel.Foreachに切り替えました。 –

+0

Parallel.Foreachはすべてのスレッドが完了するまで実行をブロックしますが、残念ながらUIが更新されることもありません。したがって、私のジレンマ。 –

+0

あなたのためのbackgroundworkerのアイデアを追加...幸運を! –

0

:ここで私は今これをやっている方法の例ですリアクティブフレームワーク(NuGet "System.Reactive.Windows.Forms")。次に、あなたのコードは次のようになります。

private void button2_Click(object sender, EventArgs e) 
    { 
     var allLinesFromFile = File.ReadAllLines(_path); 
     progressBar1.Minimum = 0; 
     progressBar1.Maximum = allLinesFromFile.Length; 

     IDisposable subscription = 
      allLinesFromFile 
       .ToObservable() 
       .SelectMany(f => Observable.Start(() => DoSomething(f))) 
       .ObserveOn(this) 
       .Do(x => progressBar1.Value += 1) 
       .Subscribe(x => { },() => 
       { 
        var postingComplete = MessageBox.Show("The posting is complete!", "Record Poster", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
        if (postingComplete == DialogResult.OK) 
        { 
         Application.Exit(); 
        } 
       }); 
    } 

    private void DoSomething(string record) 
    { 
     System.Threading.Thread.Sleep(5); 
    } 

あなたが早くそしてちょうどsubscription.Dispose()を呼び出し、これを停止する必要がある場合。私はこれをテストし、それは私のために正常に動作します。

+0

これを解決策として検討しています。提案していただきありがとうございます。 –

-1

背景ワーカー:

**Backgroundworker (System.ComponentModel)** 

BackgroundWorker loader = new BackgroundWorker(); 
    loader.DoWork += load_Specials_BW_Thread; 
     loader.WorkerReportsProgress = true; 
     loader.ProgressChanged += load_Special_Feeds_Progress_Changed; 
    private void load_Specials_BW_Thread(object sender, DoWorkEventArgs e) 
    { 

     int pctComplete = (int)Math.Floor(ptComplete * 100);//recs done/total recs 
     (sender as BackgroundWorker).ReportProgress(pctComplete); 
    } 

幸運!

関連する問題