ものがたり(旧)

atsushieno.hatenablog.com に続く

BackgroundWorker

マルチスレッドプログラミングに特に深い造詣があるわけでもない僕が実装してみますよ。おーこわ。

小ネタその1。RunWorkerCompletedEventArgs.UserState

public RunWorkerCompletedEventArgs (
object result, Exception error, bool cancelled)

doh.

どうやってもUserStateは渡せません。

ちなみに既知らしい。

その2。.NET 2.0ではWindows FormsのBeginInvoke()まわりが厳しくなっていると聞く。全く試したことがないのでやってみた:

using System;
using System.Threading;
using System.Windows.Forms;

public class TestForm : Form
{
public static void Main ()
{
Application.Run (new TestForm ());
}

Label label = new Label ();
Thread t;

public TestForm ()
{
t = Thread.CurrentThread;
Button button = new Button ();
button.Top = 100;
this.Controls.Add (label);
this.Controls.Add (button);
button.Click += delegate (object o, EventArgs e) {
new Thread (new ThreadStart (delegate () {
DoPrintLabel ();
})).Start ();
};
}

void DoPrintLabel ()
{
Console.WriteLine (Thread.CurrentThread == t);
label.Text += "_ ";
}
}

例外、投げられません…そういう話じゃないの??

その3。monoのSynchronizationContext.Post:

public virtual void Post (SendOrPostCallback d, object state)
{
d.BeginInvoke (state, null, null);
}
ひえぇ…全然contextがSynchronizedじゃないよコレ。でもランタイムのちょっとした部分に踏み込まないと実装できなさげなので(w とりあえず報告して様子見ということにするのだ。

System.Windows.Forms.Control.BeginInvoke()の実装が使い回せるかと思ったんだけど、どうやらプラットフォーム依存コードになっていて、XplatUIX11だと非同期のままで実行しているようだ。*1

*1:ちなみにXplatUIOSXではNotImplementedException(w