これは私の最初の投稿です。実際、私は通常、ここで見つけることができる素晴らしい投稿データベースですべての問題を解決します。しかし、私は実際に今立ち往生しています:
COMオブジェクトを含むMVVMに続くプロジェクトに取り組んでいます。調査中に読んだように、COM オブジェクトにはそれを作成したスレッドからのみアクセスできることがわかりました。私のCOMオブジェクトは次のインターフェースを実装しています
interface IComUpdate
{
void Update();
}
そのため、COM オブジェクトを作成すると、更新があるたびに (いつ、ランダムかはわかりません)、COM サーバーは、Update()
実装した COM オブジェクト クラスの を呼び出します。
私の目標は、COM オブジェクトが UI スレッドとは独立して存在する COM オブジェクト スレッドに名前を付けて、別のスレッドを作成することでした。そのため、更新があるたびに、UI スレッドとは別のスレッドで処理します。
実際にそれは働いています:
ViewModel の冒頭で、特定のオブジェクトのコレクションを作成します。
このオブジェクトModelObj
は、モデルの一部であり、いくつかの変数の初期化とは別に、アプリケーションが COM オブジェクトの新しいスレッドを作成して開始する静的コンストラクターを定義します。
Thread t = new System.Threading.Thread(() =>
{
System.Threading.Thread.CurrentThread.Name = "Thread of COM Object";
IComUpdate myComObj;
myComObj = (IComUpdate)Activator.CreateInstance(blabla);
Application.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
それは実際には非常にうまく機能しUpdate()
ます.COMオブジェクトの実装では、スレッドが作成されたばかりでUIスレッドではないことが実際にわかります。
今問題はこれです: これModelObj
は私が作成するINotifyPropertyChanged
インターフェイスを実装します。
私の考えは次のとおりです。COM オブジェクトが更新を受け取るたびに、COM オブジェクト スレッドからデータを処理し、このスレッドからインスタンスのいくつかのプロパティを更新します。したがって、これらのプロパティは、私のスレッドと UI スレッドModelObj
のプロパティの変更を発生させます。ModelObj
ユーザー インターフェイスを更新します。
UI の更新に時間がかかりすぎるとUpdate()
、画面に表示されないものもあるかもしれませんが、COM オブジェクトはそれらをModelObj
インスタンスに記録するので、UI がすべての更新をキャッチすることはあまり重要ではありません。COM オブジェクトは必要ありませんでした。 UI が更新されて再度呼び出されるまで待機する必要があります。
RaisePropertyChanged("property")
たくさんの投稿を読んで、失敗するだろうと思いました。
実際には、COM オブジェクトのスレッドでもRaisePropertyChanged
正常に実行されるため、コードをトレースすると、ViewModel アセンブリに切り替わることがわかります。
// Here I'm still in the thread of my COM object!
base.NotifyOfPropertyChange<string>(() => this.property)
そしてUIアップデート。
注:私は、WPF のビューと ViewModel の間のバインドに Caliburn Micro を使用しています。
なので、これ以降は追跡できませんbase.NotifyOfPropertyChange<string>(() => this.property)
。Caliburn がスレッドの切り替えを処理しているのかもしれませんが、これは実際には私の問題ではありません。
私が言えることは、私の COM オブジェクト スレッドは、UI が更新されて私RaisePropertyChanged("property")
の .
UI が実際に更新されるかどうかを知らずに、COM オブジェクト スレッドを更新して、ModelObj
更新するメッセージを UI に送信し (これの一部のフィールドが変更されたため)、すぐModelObj
に続行する必要があります。
誰かがこの振る舞いについて考えを持っていますか?
どうもありがとうございました。
####アップデート####
このような迅速な回答に感謝します。
Zdeslav Vojkovicが示唆したように、私は実際にやった:
常に GUI スレッドから GUI を更新する必要があります
完全を期すために、私が行った方法は次のとおりです。
私のビューはコード ビハインドのない完全な WPF であるため、BeginInvoke を呼び出すためのコントロールやフォームがないため、ModelObj の静的コンストラクターで、BeginInvoke を呼び出すことができるようにするためだけに、UI スレッドから非表示のコントロールを作成しました。 .
だから私はそれを宣言しました:
public static Control mInvokeControl;
delegate void MyDelegate();
private MyDelegate _NotifyDelegate;
そして、私のオブジェクトの静的コンストラクターでこれを行いました:
mInvokeControl = new Control();
mInvokeControl.CreateControl();
通常のコンストラクターでは、次のようにデリゲートを初期化します。
_NotifyDelegate = new MyDelegate(this.NotifyByInvoke);
次に、このように使用した後:
ModelObj.mInvokeControl.BeginInvoke(this._NotifyDelegate );
メソッドは次のとおりです。
public void NotifyByInvoke()
{
RaisePropertyChanged("Update");
}
すべて正常に動作します!