2

ログイン時にビジー インジケータを有効にしようとしています。問題は、すべての実行が完了するまで有効にならないことです。できるだけ早くインジケーターを開始するためにログインしたらすぐに UI を更新するようにスレッドに指示するにはどうすればよいですか?

    private void LoginButton_Click(object sender, RoutedEventArgs e)
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
            radBusyIndicator.IsBusy = true;
            //var backgroundWorker = new System.ComponentModel.BackgroundWorker();
            //backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(backgroundWorker_DoWork);
            //backgroundWorker.RunWorkerAsync();
        }));

        string error = string.Empty;
        long userId = 0;

        //Login code here....
        //...........  bunch of other code. etc..

     }
4

2 に答える 2

9

UI スレッドが解放されるとすぐに UI が更新されます。Dispatcher.Invoke既に UI スレッドにいるため、この場合は必要ありません。

ここで重要なのは、「作業」をバックグラウンド スレッドに移動することです。

private void LoginButton_Click(object sender, RoutedEventArgs e)
{
    radBusyIndicator.IsBusy = true;
    LoginButton.IsEnabled = false; // Prevent clicking twice

    string error = string.Empty;
    long userId = 0;

    // Start this in the background
    var task = Task.Factory.StartNew(()=>
    {
        //Login code here....
        //...........  bunch of other code. etc..
    });

    // Run, on the UI thread, cleanup code afterwards
    task.ContinueWith(t =>
    {
        // TODO: Handle exceptions by checking t.Exception or similar...

        radBusyIndicator.IsBusy = false;
        LoginButton.IsEnabled = true;
    }, TaskScheduler.FromCurrentSynchronizationContext());
 }

C# 5 を使用している場合は、ログインとその他のコードを非同期にすることで、これを簡素化できます。

private async void LoginButton_Click(object sender, RoutedEventArgs e)
{
    radBusyIndicator.IsBusy = true;
    LoginButton.IsEnabled = false; // Prevent clicking twice

    long userId = 0;

    // Call async method with await, etc...
    string error = await DoLoginAsync(userId);

    var result = await BunchOfOtherCodeAsync();

    radBusyIndicator.IsBusy = false;
    LoginButton.IsEnabled = true;
 }
于 2013-06-27T20:58:33.470 に答える
0

バックグラウンド ワーカー スレッドを使用して、その 2 つの eventHandler を、作業したいイベントにサブスクライブできます。

BackgroundWorker Worker=new BackgroundWorker();
worker.DoWork+=Yorevent which will do the timeTaking Task();
Worker.RunWorkerCompleted+=YOurEvent which will Update your UI after the work is done();
worker.RunWorkerAsync();

このようにして、スレッドエラーも発生しません..

TimeTaking TAsk の開始時に BusyIndi​​cator を有効にし、timeTaking タスクが完了したら、RUNWorkerCompleted イベントで Busy Indicator を無効にします。

于 2013-06-29T10:50:44.027 に答える