web-dev-qa-db-ja.com

UIスレッドをブロックすることは良い考えですか?

たとえば、ボタンがクリックされたときに再生されるアニメーションを含むカスタムボタンを作成しました。アニメーションには500ミリ秒かかります。その間(アニメーションが終了するまで)、ボタンは入力を受け取らないため、他のアイテムはボタンの終了を待機します。

私がこのように実装した場合:

public async void Clicked()
{
    await Animate();
}

uIスレッドはブロックされず、その間、ユーザーはボタンをもう一度押すか、Backボタンを押すか、私が彼にしたくない他のことを行うことができます。

私がこのように実装した場合:

public void Clicked()
{
    Animate();
}

uIスレッドは、Animateが戻るまでブロックされます。

私の質問は、ユーザーがアイテムをダブルクリックできないようにするためにUIスレッドをブロックすることは良い考えですか?

いいえの場合、どのアプローチが良いと考えられますか?

4
nicks

より良いアプローチは、次のように、アニメーションが現在実行されているかどうかを追跡することです。

bool animationRuns=false;

async void Clicked()
{
    if(animationRuns)
       return;
    animationRuns=true;
    await Animate();
    animationRuns=false; 
}

このようにすると、アニメーションの実行中もUIは応答しますが、ユーザーが誤って2度起動することはありません。アニメーションの実行中に無効にする他のイベントがある場合は、animationRunsフラグをそこでテストすることもできます。

6
Doc Brown

まず、アプリケーションのOnIdleハンドラーをセットアップします。 WinFormsアプリケーションの場合、これは非常に簡単です。WPFの場合、ここにリストされているいくつかの代替案があります https://stackoverflow.com/questions/3872992/how-do-we-do-idle-time-processing-in -wpf-application

このハンドラーで、アプリケーションがビジー状態のときに無効にするすべてのコントロールの有効状態を設定します。有効な値にはビジー状態の条件を使用します。

2
Martin Maat