尝试了解ThreadPool
方法QueueUserWorkItem
的两种变体。
string bigS = "Big Stupid";
ThreadPool.QueueUserWorkItem( s =>
{
Console.WriteLine("Working on a thread from threadpool B");
Console.WriteLine("s = {0}", s.ToString());
}, bigS);
ThreadPool.QueueUserWorkItem(MethodA, bigS);
MethodA
的定义如下。
private static void MethodA(object o)
{
Console.WriteLine("o = {0}", o.ToString());
}
两种方式都很好。但是QueueUserWorkItem
还有另一种变体,它接受一个采用单个参数并返回void的方法的委托。所以methodA
应该没问题。但是由于我没有在o
中传递对象MethodA
,因此跟随代码抛出异常。我不想在o
中检查MethodA
的空值。如何将第二种情况中的bigS
传递给MethodA
?
ThreadPool.QueueUserWorkItem(MethodA);
替代方式可能是这样的。但我想通过并访问o
。我能做到吗?
ThreadPool.QueueUserWorkItem( o =>
{
Console.WriteLine("Working on a thread from threadpool");
});
答案 0 :(得分:1)
It's not very clear from the MSDN documentation, but
ThreadPool.QueueUserWorkItem(callback);
is equivalent to
ThreadPool.QueueUserWorkItem(callback, null);
If optional parameters existed at the time this API has been made, most probably there would have been just one method like
public static bool QueueUserWorkItem(WaitCallback callBack, object state = null)
But for one thing the documentation (the Remarks section) is clear - if you want your callback to receive something, you need to pass it, i.e. use the overload with state
argument.
答案 1 :(得分:1)
The o in
ThreadPool.QueueUserWorkItem( o =>
{
Console.WriteLine("Working on a thread from threadpool");
});
will always be null. It is just there because QueueUserWorkItem
wants a WaitCallback
and that is defined as an Action<object>
. I think microsoft devs just don´t wanted to define a second WaitCallback
delegate. And ThreadPool
was implemented before Action
and Func
existed.
You could capture the bigS
with your lambda
string bigS = "Big Stupid";
ThreadPool.QueueUserWorkItem( _ =>
{
Console.WriteLine("Working on a thread from threadpool B");
Console.WriteLine("s = {0}", bigS);
});
or like this if you have to use MethodA
string bigS = "Big Stupid";
ThreadPool.QueueUserWorkItem( _ =>
{
MethodA(bigS);
});