Gomathipriya
Gomathipriya

Reputation: 945

Using methods in thread pool

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

Answers (4)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186833

According to MSDN

http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(System.Threading.WaitCallback);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true

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

user1928346
user1928346

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

Alexei Levenkov
Alexei Levenkov

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

Adil
Adil

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

Related Questions