2007/12/31

BeginInvoke

C#でWiimoteLibいじってて、C#について気づいたことの備忘録。。。

下記のようなソースでWiimoteChanged()が別スレッドで実行されていた場合に、WiimoteChanged()の中でフォームオブジェクトにアクセスすると"別スレッドから実行された"とのエラー(警告)が出てしまう。

この場合にBeginInvokeで非同期(遅延?)呼び出しとやらを使ってあげると、BeginInvokeで指定した関数はメインスレッドで実行されるらしい。


たとえばメインスレッドで実行されるForm1()のスレッドIDが10で、WiimoteChanged()がスレッドID11で実行されたとする。

ここで、WiimoteChanged()からBeginInvoke()で実行されるUpdateWiimoteState()はスレッドID10で動くようだ。


ってことはソケットとかのイベントで別スレッドからデリゲート関数が実行された場合は、BeginInvoke()で実際の処理を呼び出してあげればいいのかな?
ただ、BeginInvoke()で調べてると、BeginInvoke()で呼び出す関数にはいろいろと制約があるらしいので、このあたりはもう少し調査する必要アリかな?

Invoke()だとかBeginInvoke()の話はここを見れば詳しく分かりそうですね。



private delegate void UpdateWiimoteStateDelegate(
WiimoteChangedEventArgs args );

private Wiimote wiimote = new Wiimote();

public Form1()
{
Debug.WriteLine( "Form1 Thread id : " +
Thread.CurrentThread.ManagedThreadId );

InitializeComponent();

wiimote.WiimoteChanged += new WiimoteChangedEventHandler(
WiimoteChanged );
}

private void UpdateWiimoteState( WiimoteChangedEventArgs args )
{
Debug.WriteLine( "UpdateWiimoteState Thread id : " +
Thread.CurrentThread.ManagedThreadId );
}

private void WiimoteChanged( object sender, WiimoteChangedEventArgs args )
{
Debug.WriteLine( "WiimoteChanged Thread id : " +
Thread.CurrentThread.ManagedThreadId );
BeginInvoke( new UpdateWiimoteStateDelegate( UpdateWiimoteState ),
args );
}

2 件のコメント:

匿名 さんのコメント...

意外と更新してるみたいなので(w)リンクはっておきました:)

かおるん さんのコメント...

見られてる(笑)
リンクサンキュー☆