-1

この質問を削除するにはどうすればよいですか? 当初、この問題は DoEvents に関連していると考えていましたが、そうではないことが判明しました。ここに質問を再投稿しました: http://goo.gl/VpAEKに問題のより適切な説明を付けてください。

ありがとう - これを処理する方法についてのガイダンスに感謝します...


まず、一般的な概念が以前に尋ねられたので、私はこの質問を知っています - 私は(うまくいけば)尋ねる特定のバリエーションを持っています. また、Application.DoEvents() を使用しない特定の理由を理解していること、および可能な限り使用しないことを前もって全員に保証し、複数のスレッドで (Application.DoEvents() の関与なしに) 問題を解決できるようにすることも言い始めます。私たちのアプリ。

そうは言っても、それフレームワークの一部です - そして、それがその場所を持っている特定の状況があると思います.

私が質問している特定のケースは、純粋に UI が関係する単一スレッドの状況です。(私が理解しているように)定義上、これはバックグラウンド スレッドでは実行できません。より具体的には、フォームに多数の UI 要素をロード/構成していますが、完了するまでに 1 ~ 2 秒かかる場合があり、このプロセス中に何が起こっているかを示すラベルを更新したいと考えています。バックグラウンド スレッドで実行する重労働/作業は実際にはありません。それはすべて UI です。

4 つのラベル テキストが変更された後に Application.DoEvents() 呼び出しがない場合、ラベル自体は再描画されません。純粋な UI のシングル スレッド環境でこれを別の方法で解決する代替案を誰かが提案できる場合、私はすべて耳にします。

問題は、散発的に、私がまだ特定しようとしている場合に、 Application.DoEvents() が単に返されないことです。

DoEvents() メソッドに関するすべての苦情 (そのほとんどは完全に有効です!!!) と、それが引き起こす可能性のあるさまざまな問題を本当に理解しています! したがって、理想的には、DoEvents 呼び出しの長所/短所について大きな議論に巻き込まれることなく (このトピックに関する他のほとんどすべてのスレッドが行っているように) - 私が答えたい特定の質問は - 誰かが何か理由を思いつくことができますか? DoEvents が単にハングするのはなぜですか? (つまり返さない)?

DoEvents() 呼び出し自体について議論したい場合は、ここにその長所と短所の優れた説明があります: http://goo.gl/4BtZf

  • 私たちのユーザーは、これはアプリの使用中に発生するのではなく、コンピューターからしばらく離れたときにのみ発生するように見えると報告しています (スクリーン セーバーの関与でしょうか?)。お客様のコンピューターをリモートで表示します。
  • アプリを最小化すると、より多く発生すると主張するユーザーがいます。
  • アプリが最小化されていると、IE や Outlook で何らかの作業を行っていると、より多く発生すると主張するユーザーがいます。

内部的には、ほぼ完全に再現できませんでしたが、今朝、ネットワーク接続を 1 ~ 2 分間無効にし、サーバーへの VPN 接続を数分間行うなど、上記のすべてを行ったときを除いて、すべてアプリが最小化されていました。

この後 (文字通り初めて社内で再現できました)、アプリがハングし、プロセスにアタッチすると Application.DoEvents() 行でハングしました。2 回線方式:

label.Text = "Foo"; Application.DoEvents();

複数の追加テスト (同じアクションを実行しようとする) では、問題を再現できませんでした。

助言がありますか?ありがとう。


編集: 特に DoEvents に関する質問に答えようとすることはタブーですか? 私は StackOverflow に比較的慣れていないので、すでに 2 票の反対票を獲得した理由について少し混乱しています。

私はこの質問が他のスレッドで何度も尋ねられるのを見てきました. 私は特に最初の質問で思いやりを持ち、この場合にそれを使用した理由を説明しようとしました. 同時に、DoEvents を使用すべきではない理由について、これ以上議論することを特に避けようとしています。十分な数の人が何か悪い考えだと思うなら、stackoverflow で議論するのはタブーですか? 繰り返しますが、私はこのフォーラムに比較的慣れていないため、ここでのエチケットを理解しようとしています。ありがとう。

4

1 に答える 1

2

このタスクを実行するために他の [バックグラウンド] スレッドを利用することが間違っていると考えるのは誤りです。その道を進みたいならそれでApplication.DoEventsいい。ここに座って、それを使用してはいけないと言うつもりはありませんが、少なくとも検討する必要があります可能な代替手段として使用しないでください。あなたが言ったように、あなたがしていることは、多数の個別の UI 要素を更新することです。単一の UI タスクを実行しているのではなく、多数 (数十、数百、数千など) のタスクを実行しています。また、これらの小さなタスクをすべて管理する別のタスクもあります。この小さなタスクの管理は、UI スレッドまたは非 UI スレッドで行うことができます。UI スレッドで実行すると、すべてのサブ UI アクションが完了するまで UI がブロックされます。単に「スケジューラ」として機能する非 UI スレッドがあり、多数の小さな UI タスクを追加して完了する場合、それらの小さな UI タスクを個別に実行して、UI が何かを実行できるようにすることができます。それらのタスクの。

以下に例を示します。

private void button1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 10; i++)
        {
            Invoke(new MethodInvoker(() => updateLabel(i)));
            Invoke(new MethodInvoker(() => longerUITask(i)));
        }
    });
}

private void longerUITask(int i)
{
    //do databinding that will take a second or two
    Thread.Sleep(1000);
}

private void updateLabel(int i)
{
    label1.Text = i.ToString();
}

これを行うと効率が低下します。はい、そうなります。他のスレッド/タスクを生成したり、それらを管理したりします。ただし、そのコストで得られるのは、UI の応答性が維持されるという簡単で効果的な保証です。

于 2012-07-20T17:44:02.467 に答える