1

次々に呼び出す必要がある 2 つの非同期プロセスがあります (1 つは XML の作成backgroundworkerで、もう 1 つは最初のプロセスで作成された XML ファイルを使用する珍しい BW で​​す)。これらのスレッドの主な理由は、UI のフリーズを停止し、進行状況バーを介してステータスの更新を提供することです。このような同期アプローチは望ましくない/不可能であるためです。

if (!CreateXMLBW.IsBusy)
{
CreateXMLBW.RunWorkerAsync("");
}
if (!CreateRarBW.IsBusy)
{
CreateRarBW.RunWorkerAsync();
}

プロセスを個別に使用できるため、最初の完了イベント内に 2 番目の BW を配置することはできません。そのため、XML ファイルを作成したいだけであれば、それを行うことができます。

AutoResetEventandを使用してみWaitOneましたが、これは (何らかの理由で) まだ機能しません。

メイン UI スレッドをフリーズせずに BW が完了するのを待つ方法は他にありますか?

4

4 に答える 4

1

この例のようなタスクを使用することもできます。

class Program
{
    static XElement CreateXml()
    {
        System.Threading.Thread.Sleep(1000);
        return XElement.Parse(@"<FooBar>Hi!</FooBar>");
    }

    static void ProceedXml(XElement xml)
    {
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine(xml.ToString());
    }

    public static void Main()
    {
        Task.Factory.StartNew<XElement>(CreateXml)
                    .ContinueWith(t => ProceedXml(t.Result));
        Console.ReadKey();
    }
}
于 2012-05-18T09:44:57.217 に答える
1

イベントを待つまで UI をブロックしたくない場合 (つまり、何かをするつもりだと思いDoWork()ます) の最後にイベントを発生させることができ、UI スレッドはそれを受け取ることができます。

4.0 を使用していて、BackgroundWorker の使用を避けることができる場合は、TPLのTask.ContinueWithを使用できます。

擬似コードは次のようになります。

   Action action =(() => DoWorkMethod());
   Task.Factory.StartNew(() => action()).ContinueWith(()=>CallAfterComplete());
于 2012-05-18T09:39:57.240 に答える
1

あなたのシナリオはまさにそのTaskために設計されたものです。特定のケースでは、コードは次のようになります。

public delegate void UpdateUI(int progress);

private void RunOneAfterAnotherAsync()
{
    Task<XmlElement> task = Task.Factory.StartNew<XmlElement>(CreateXMLBW);
    task.ContinueWith(CreateRarBW);
}

private XmlElement CreateXMLBW()
{
    // your code

    // progress
    progressBar1.Invoke((UpdateUI)UpdateProgressBar, new object[] {progressValue});

    // result
    XmlDocument doc = new XmlDocument();
    return doc.CreateElement("element");
}

private void CreateRarBW(Task<XmlElement> task)
{
    CreateRarBW(task.Result);
}

private void CreateRarBW(XmlElement arg)
{
    // your code
}

public void UpdateProgressBar(int value)
{
    this.progressBar1.Value = value;
}

RunOneAfterAnotherAsyncはブロックされておらず、2 つのメソッドが次々と非同期で実行されます。例外なく終了するCreateRarBW場合にのみ実行されますが、 で追加の引数を使用して変更できます。CreateXMLBWContinueWith

この例が示すよりもはるかに多くのことができます。Taskクラスを調べることをお勧めします。

編集

最初のタスクから 2 番目のタスクに渡される結果を組み込むために、例を少し拡張しました。また、UI の進行状況の例を追加しました。

于 2012-05-18T10:25:40.947 に答える
0

UIは、最初のBWでRunWorkerCompletedイベントを処理し、2番目のBWを呼び出すことができます。

于 2012-05-18T09:46:52.140 に答える