2011-03-11 9 views
2

私は本当に奇妙な状況に遭遇しました。これはとてもシンプルなはずですが、私はなぜそれが起こっているのか分かりません。C#プログレスバーが協力していません

私はマーキープログレスバーを初期状態としてvisible = falseに設定しました。それから、ランタイム中のある時点で私は自分の関数の1つを呼び出し、それを呼び出す前にPBをvisible = trueに設定し、関数が終了したらvisible = falseに戻します。これはもっと簡単ではありません。

If (something) 
{ 
    pb.visible=true; 
    runMyfunction(x, x, x, x,); 
    pb.visible=false; 
} 

問題は私がPBを見たことがないということです。私の機能をコメントアウトしてfalseを削除すると、PBが表示されますが、私の機能をそこに戻すと、PBは決して表示されません。

私はさまざまなアプローチを試みました。 Ifステートメントを使用して、関数に触れる前に進捗バーを取得し、PBを隠したままにしておきます。

何か不足していますか?これはあまりにも複雑なようには見えません。オブジェクトの表示、関数の実行、オブジェクトの非表示。右?

例えば::)あなたrunMyFunction()メソッド呼び出しApplication.DoEvents()の内部

+4

は、このリサイズまたはasp.netまたはWPFまたは何ですか? – kprobst

+0

あなたはASP.NETのWinFormsプログレスバーを参照していますか? – TheBoyan

答えて

7

私の推測はmyRunFunction()で、UIスレッドで動作します。

BackgroundWorkerの中で実行し、RunWorkerAsyncを呼び出す前にProgressBarを起動し、RunWorkerCompletedイベントで停止してください。

コード例で編集:

public class SomeClass 
{ 
    private BackgroundWorker _myFunctionBackgroundWorker; 
    private SomeProgressBar pb; 

    public SomeClass() 
    { 
     _myFunctionBackgroundWorker = new BackgroundWorker(); 
     _myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork; 
     _myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted; 

     pb.visible = true; 
     _myFunctionBackgroundWorker.RunWorkerAsync(); 
    } 

    private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     runMyfunction(); 
    } 


    private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     pb.visible = false; 
    } 
} 
+0

チャームのように働いた!ありがとうございました。しかし、1つの問題があります。私の関数にはいくつかのcatchステートメントがあり、それらをヒットするとクロススレッドエラーが発生します。私は、バックグラウンドワーカーによって開始された元のスレッドにカプセル化されていないと考えています。いずれにせよ、私はそれを修正することができますか? – GeneK

+0

気にしないで、私はそれを得た。私の機能を少し並べ替える必要があったが、一度すべての結果をe.Resultに渡すと、すべてが完璧に機能している!私はbackgroundworkerを使って正しいアプローチでセットアップを取ってくれてありがとう。 – GeneK

2

は再描画とウィンドウメッセージループを処理するためにアプリを強制的に

void myRunFunction() 
{ 
    while (someFlag) 
    { 
    // do work 
    pb.Value = someValue; 
    Application.DoEvents(); 
    } 
} 
1

機能が実行中であり、バーを表示するには速すぎる可能性があります。私はこれが数回前に起こったことを知っています。

7

これは、関数がUIスレッドを連結しているためです。 ProgressBarを可視に設定するには、UIスレッドを描画するためにUIスレッドを解放する必要がありますが、描画する時間が決して与えられない関数を処理し続けます。 Application.DoEventsこれは、いくつかのウィンドウメッセージを処理するのに十分長くあなたのメソッドを処理するのを止めます(そして関連する図面を実行します)。

Application.DoEventsの大きな問題は、あなたがよ、あなたはrunMyfunction()あなたは常にあなたのPBを描くことができるようにApplication.DoEventsをコールする必要があるとしているから、あなたのプログレスバーを更新していると仮定して、またはあなたがそれを見ることができますが、ということですそれが更新されることはありません。

より良い解決策は、runMyfunction()コールをバックグラウンドスレッドにプッシュし、そこから非同期でプログレスバーを更新することです。もちろん、これはずっと複雑ですが、ユーザーエクスペリエンスを向上させます。

+0

この状況では、BackgroundWorkerが理想的かもしれません。それはあなたが必要とする多くのメソッドをカプセル化します。 – ChrisG

+0

これは問題を解決するので素晴らしいです。しかし、関数が〜10秒間実行されている間、私のアプリケーションはまだ結ばれているので、マーキーは動かない。関数が実行されている間にマーキーを表示し、最後に削除するという簡単なルーティングを行っています。私はbackgroundworkerを使ってROBOlavの提案を試みるつもりです。 – GeneK