私は次のコードで遊んでいます:
class RunMeBaby
{
public void Start()
{
while (true)
{
Console.WriteLine("I'm " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
}
}
}
class Program
{
static void Main(string[] args)
{
RunMeBaby r = new RunMeBaby();
Thread t = new Thread(r.Start); // ParameterizedThreadStart delegate
r = null;
GC.Collect(GC.MaxGeneration);
t.Start();
r = new RunMeBaby();
t = new Thread(() => r.Start()); // ThreadStart delegate
t.Start();
//Thread.Sleep(1000);
r = null;
}
}
mainの最初の部分は問題なく実行されますが、Thread.Sleep()
メソッドの呼び出しにコメントを付けると2番目の部分は失敗し、null例外が発生します。
私の理解では、ラムダ式が遅延評価されているため、新しいスレッドが十分に速く開始されず、メインスレッドが最初に設定r
される可能性があります。null
ここで、この「2番目の部分」をローカルスコープを持つ静的メソッドに入れるr
と、問題は解消されました。しかし、その特定のケースでは、問題がスレッドスケジューラによって隠されているかどうか、おそらく別のワークロードを持つ別のマシンで問題が発生する可能性があるかどうか疑問に思います。r
または、ラムダ式について、スコープ外であっても、に設定されていない限り、何らかの形で参照されることを保証する何かがありnull
ますか。
そして最終的には、ParameterizedThreadStart
デリゲートをできるだけ使用することを検討する必要があるのか、それとも特定の条件を尊重してラムダを有効に保つためにラムダに固執する必要があるのか疑問に思います。