1

wpf 拡張ツールキットの BusyIndi​​cator があり、完了するまでに時間がかかる関数を実行しています。時間のかかるタスクを別のスレッドで実行すると、その別のスレッドから ObservableCollection にオブジェクトを挿入しようとしているため、NotSupportedException が発生します。可能であれば、コードのリファクタリングに多くの時間を費やしたくありません...代わりに別のスレッドでインジケーターの可視性を設定できる方法はありますか?

編集

ThreadStart start = delegate()
  {
      System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
          {
              IsBusy = true;
          }));
   };

new Thread(start).Start();                                
longRunningFunction();

これは私にとってもうまくいきませんでした。

4

2 に答える 2

0

バックグラウンド ワーカーから UI コントロールにアクセスすることはできません。通常は、BackgroundWorker.RunWorkerAync() を呼び出す前に IsBusy を true に設定し、BackgroundWorker.RunWorkerCompleted イベント ハンドラで IsBusy を false に設定します。次のようなものです:

Backgroundworker worker = new BackgroundWorker();
worker.DoWork += ...
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
     IsBusy = false;
};
IsBusy = true;
worker.RunWorkerAsync();

Dispatcher を使用して、DoWork イベント ハンドラ内で ObservableCollection に項目を追加できます。

編集:ここに完全な解決策があります

        private void Button_Click(object sender, RoutedEventArgs e)
    {
        //on UI thread
        ObservableCollection<string> collection;

        ThreadStart start = delegate()
        {
            List<string> items = new List<string>();
            for (int i = 0; i < 5000000; i++)
            {
                items.Add(String.Format("Item {0}", i));
            }

            System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
            {
                //propogate items to UI
                collection = new ObservableCollection<string>(items);
                //hide indicator
                _indicator.IsBusy = false;
            }));
        };
        //show indicator before calling start
        _indicator.IsBusy = true;
        new Thread(start).Start();      
    }
于 2011-08-31T20:57:37.210 に答える