2

プログレス バーを表示しながら、 BackgroundWorkerを使用して別のスレッドでアクションを実行するProgressBar フォームを作成しようとしています。

現時点では、私の ProgressBar クラスには ProgressBarControl が含まれており、コードは次のようになります。

public partial class QTProgressBar : DevExpress.XtraEditors.XtraForm
{
    private BackgroundWorker m_backgroundWorker;
    private AutoResetEvent m_resetEvent;

    public QTProgressBar()
    {
        InitializeComponent();

        InitializeProgressBar();

        m_backgroundWorker = new BackgroundWorker();
        m_backgroundWorker.WorkerReportsProgress = true;
        m_backgroundWorker.WorkerSupportsCancellation = true;
        m_backgroundWorker.DoWork += new DoWorkEventHandler(m_backgroundWorker_DoWork);
        m_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(m_backgroundWorker_ProgressChanged);
        m_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_backgroundWorker_RunWorkerCompleted);
        m_resetEvent = new AutoResetEvent(false);
    }

    void m_backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        m_resetEvent.Reset();

        CloseProgressBar();
    }

    void CloseProgressBar()
    {
        if (InvokeRequired)
        {
            Invoke( new MethodInvoker(CloseProgressBar));
            return;
        }
        this.Close();
    }

    void m_backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        Action operation = e.Argument as Action;
        operation();
    }

    public void StartAsyncTask(Action operation)
    {
        m_resetEvent.Set();
        m_backgroundWorker.RunWorkerAsync(operation);
    }
}

今のところ、ポップアップを表示したいときは次のようにします。

QTProgressBar op = new QTProgressBar();
op.StartAsyncTask(() => LongDurationOperation(5, 5));
op.ShowDialog(); // i would like to move this inside the ProgressBar class.
//Thread gets blocked here until operation finishes. 

LongDurationOperation は次のとおりです。

public void LongDurationOperation(int n, int m)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            Thread.Sleep(100);
        }
    }
}

を呼び出すスレッドをブロックしたくない

ShowDialog() 

プログレスバー クラスのメソッド。これを ProgressBar クラス内のどこかに移動すると、スレッドがブロックされ、操作が実行されません。

Showdialog() メソッドを呼び出すスレッドのブロックを回避することは可能ですか?

また、このクラスを改善する方法についてヒントを教えていただけますか?

どうもありがとう。

4

1 に答える 1

6

フォームに存在する 2 つの異なる呼び出しがあります。

myForm.ShowDialog();

それを呼び出すスレッドをブロックするモーダル バージョンです。これは、他のアクション (保存ダイアログなど) が実行されないようにする必要があるポップアップに使用されます。

myForm.Show(IWin32Window owner);

ノンモーダル版です。現在のスレッドはブロックされませんが、結果は返されません。ただし、多くの場合、次のように所有者に渡す必要があります。

myForm.Show(this);
于 2012-11-12T10:15:01.367 に答える