3

質問が意味をなさないかもしれないことはわかっています。説明する方法を考えるのに苦労しているので、役立つコードのスニペットを示します。Visual Studio Express 2010 で Winforms を使用しています。

private void button1(object sender, EventArgs e)
    {
        txtOutput.Text += "Auto-collecting variables. This may take several minutes";
        string v = foo();
        txtOutput.Text += "\n" + v;
        string b = bar();
        txtOutput.Text += "\n" + b;

        txtOutput.SelectionStart = txtOutput.Text.Length;
        txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
    }

基本的に、ユーザーがボタン1をクリックすると、「変数の自動収集...」がテキストボックスに表示され、foo()が実行されて表示され、bar()が実行されて表示されます.

現在起こっていることは、foo() と bar() が実行され、foo() と bar() が実行された後にすべてが一度に表示されることです (関数には数分かかります)。とにかくこれを修正する方法はありますか、それとも回避策はありますか?

編集: C# のバージョンは 4.0 です。4.5 または 5.0 に更新した場合、.NET 4.5/5.0 がインストールされていないコンピューターで .exe を実行できますか?

4

5 に答える 5

6

C# 5.0 では、これを簡単に行うことができます。

Task.Runを使用してバックグラウンド スレッドで実行時間の長いタスクawaitを実行し、非同期タスクの実行中に UI スレッドをブロックすることなく、残りのメソッドを UI スレッドで継続として実行します。

private async void button1(object sender, EventArgs e)
{
    txtOutput.Text += "Auto-collecting variables. This may take several minutes";
    string v = await Task.Run(() => foo());
    txtOutput.Text += "\n" + v;
    string b = await Task.Run(() => bar());
    txtOutput.Text += "\n" + b;

    txtOutput.SelectionStart = txtOutput.Text.Length;
    txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
}

次のように C# 4.0 で同じことを行うことができます (最初のソリューションは、コンパイラによって同様のものに変換されます)。

private  void button1(object sender, EventArgs e)
{
    txtOutput.Text += "Auto-collecting variables. This may take several minutes";
    Task.Factory.StartNew(() => foo())
        .ContinueWith(t => txtOutput.Text += "\n" + t.Result
            , TaskScheduler.FromCurrentSynchronizationContext())
        .ContinueWith(t => bar())
        .ContinueWith(t =>
        {
            txtOutput.Text += "\n" + t.Result;
            txtOutput.SelectionStart = txtOutput.Text.Length;
            txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
        }
            , TaskScheduler.FromCurrentSynchronizationContext());
}
于 2013-06-12T15:37:22.437 に答える
0

バックグラウンド プロセスを使用する (他の回答を読む) のが正しい方法ですが、非常に簡単な回避策を見ている場合はApplication.DoEvents()、TextBox を更新した後に呼び出すことができます。ほとんどの場合、この呼び出しによりフォームが更新され、行った変更が反映されます。

于 2013-06-12T15:36:50.317 に答える
0

txtOutput.Update()必要なことを行う必要がありますが、バックグラウンド スレッドを使用して、UI スレッドをブロックせずに長時間実行されるタスクを完了することを検討する必要があります。

于 2013-06-12T15:38:26.473 に答える