0

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)?

4 Answers 4

1

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);

Sign up to request clarification or add additional context in comments.

Comments

1

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() { 
    ...
  }

Comments

0

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));

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.