1

IIが実際のアプローチを理解できなかっただけで申し訳ありませんが、さまざまなブログ投稿を調べましたが、答えに近づいているとは感じていません.

私は基本的に時間をコストに変換するストップウォッチである WP7 アプリケーションを作成しています。

Model にはメソッド Start() および Pause() と double プロパティ Cost が含まれています。ViewModel では、基になるモデル関数をトリガーする Start() と Pause() に ICommand を使用しています。ただし、Start() を呼び出した後、増加するコストを UI に反映させたいと考えています。

私はいくつかのアプローチを検討しました:

  1. ViewModel は、自己実装されたサブスクライバー モデルを介してモデルにサブスクライブし、モデルは、モデルが実行されている間、数ミリ秒ごとにすべてのサブスクライバーに通知します。
  2. View Model の StartCommand は、数ミリ秒ごとに Cost プロパティで RaisePropertyChanged イベントを発生させるバックグラウンド ワーカーを開始します。

モデルはスレッド化をまったく必要としないため、2 番目の提案を選択しました (ユーザーが開始と一時停止を押した時間をログに記録し、これをコスト計算に使用するだけです)。http://msdn.microsoft.com/en-us/library/cc221403(VS.95).aspxに基づいてアプローチしました

ただし、これを実行しようとすると「UnauthorizedAccessException」が発生します。コードは以下のとおりです。

バックグラウンドワーカーは、コンストラクターで VM メンバーとして作成されます

public MeetingCostViewModel()
{
    _backgroundWorker = new BackgroundWorker
    {
        WorkerSupportsCancellation = true,
        WorkerReportsProgress = false,
    };
    _backgroundWorker.DoWork += DoWork;
}

StartCommand は、バックグラウンド ワーカーの実行をトリガーします

private DelegateCommand _startCommand;
    public ICommand StartCommand
    {
        get
        {
            return _startCommand ?? (_startCommand = new DelegateCommand(
                delegate
                {
                    _meetingCost.Start();
                    _keepUpdating = true;
                    if (_backgroundWorker.IsBusy != true)
                    {
                        _backgroundWorker.RunWorkerAsync();
                    }
                }));
        }
    }

そして、これはhttp://blog.lab49.com/archives/1166に基づく実際のワーカー メソッドです。

private void DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        PropertyChangedEventHandler temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs("Cost"));
        }
        Thread.Sleep(50);
    }
}

これが正しいアプローチであるかどうかはわかりませんが、ビューをデータバインドし、「コードビハインド」なしで維持したいのですが、ここでのほとんどの代替応答では、賢明なコストで回避したいコントロールの明示的な設定が必要です。

4

2 に答える 2

1

おそらく、UnauthorizedAccessException は、別のスレッドから UI オブジェクトにアクセスしていることを意味します。イベント ハンドラーが間違ったスレッドで起動します。

UI スレッドで起動する DispatcherTimer を使用するようにコードを変更します。

于 2012-04-06T22:02:21.767 に答える
0

別の解決策は、 のレポート進捗イベント ハンドラで更新を行うことですBackgroundWorker。正しいスレッドに自動的にマーシャリングします。

于 2012-04-06T22:30:04.437 に答える