Reputation: 945
I want to run a method in a thread pool. While build the following code it gives an error
No overload for 'method' matches delegate 'System.Threading.WaitCallback'.
I know where the error happens, but I don't know why:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Thread_Pool
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintNumbers));
// PrintNumbers();
}
static void PrintNumbers()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
Thread.Sleep(3000);
}
}
}
}
When the above code is rewritten as the following, it works fine.
static void PrintNumbers(object Stateinfo)
Why does this happen? Instead of using object may I use another type (like int
, float
)?
Upvotes: 0
Views: 1233
Reputation: 186833
According to MSDN
WaitCallback
delegate wants an Object
argument:
[ComVisibleAttribute(true)]
public delegate void WaitCallback(Object state)
So you should provide it even if you're not going to use it:
static void Main(string[] args) {
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintNumbers));
}
static void PrintNumbers(Object state) { // <- "Object state" is required here
...
}
If you want to leave PrintNumbers intact you can use lambda:
static void Main(string[] args) {
ThreadPool.QueueUserWorkItem(
(Object state) => { // <- You have to use "Object state"
PrintNumbers();
}
);
}
static void PrintNumbers() {
...
}
Upvotes: 1
Reputation: 513
WaitCallback is a delegate accepting the parameter object. In order to use the delegate your method has to match the delegate signature like so:
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem( new WaitCallback( PrintNumbers ) );
}
static void PrintNumbers(object a)
{
for ( int i = 0; i < 10; i++ )
{
Console.WriteLine( i );
Thread.Sleep( 3000 );
}
}
or you could simply use a lambda expression
ThreadPool.QueueUserWorkItem( a => { PrintNumbers(); } );
Functionality wise both approaches are the same. The "state" argument is only required when you intend to pass in values into your method.
Upvotes: 0
Reputation: 100620
Number and types of arguments must match when creating delegates.
In current versions of C# it is easier to use lambda expressions than explicitly typed delegates. It makes converting types easier and allows to pass strongly typed parameters
ThreadPool.QueueUserWorkItem( unused => PrintNumbers()));
int intBalue = 1;
double doubleValue = 2;
ThreadPool.QueueUserWorkItem( unused => Method(intValue, doubleValue) );
or you still can pass value as usual:
ThreadPool.QueueUserWorkItem( state => MethodTakinObject(state));
Upvotes: 0
Reputation: 148180
i know where the error happens, but i dont know why? when the above code is rewritten as following, it works fine
You have to follow the singnature that is required by WaitCallback
, as you can see the delegate definition of WaitCallback. This is why PrintNumbers
need to have a parameter of type object
.
public delegate void WaitCallback(
Object state
)
why this happens? and instead of using object may i use another type (like int, float)? is it possible?
Yes, you can use Convert.ToDouble(obj);
Upvotes: 1