Thomas
Thomas

Reputation: 34188

ThreadPool.QueueUserWorkItem with function argument

I am using C# 2.0 and want to call a method with a couple of parameters with the help of ThreadPool.QueueUserWorkItem, so I tried as follows:

ThreadPool.QueueUserWorkItem(new WaitCallback(Multiply(2, 3)));

private int Multiply(int x,int y)
{
  int z=(x*y);
  return z;
}

I am getting compilation error. So please guide me, how can I call a function with multiple arguments with ThreadPool.QueueUserWorkItem?.

I have another query that when I am using ThreadPool.QueueUserWorkItem then how to use here anonymous function as a result I can write the code there instead of calling another function. If it is possible in C# v2.0 then please guide me with code.

Upvotes: 26

Views: 49510

Answers (5)

Elad
Elad

Reputation: 1655

for passing arguments without lambda - just pack all arguments into a class/object

MyArgumentsClass  m_MyArgumentsClass = new MyArgumentsClass();
 //fill arguments in class
 ThreadPool.QueueUserWorkItem(new WaitCallback(MyFunction), m_MyArgumentsClass);  

then, in the function - cast the object into your arguments class

public void MyFunction(object msg)
{
    MyArgumentsClass  m_MyArgumentsClass = (MyArgumentsClass)msg;

Upvotes: 1

Xpleria
Xpleria

Reputation: 5853

In my case, I needed an anonymous function. i.e., write to a stream asynchronously. So I used this:

ThreadPool.QueueUserWorkItem(state => {
    serializer.Serialize(this.stream);
    this.stream.Flush();
});

Upvotes: 2

claudio
claudio

Reputation: 1564

Using a lambda expression would also work

ThreadPool.QueueUserWorkItem(state => Multiply(2,3));

Upvotes: 25

Svetlin Ralchev
Svetlin Ralchev

Reputation: 624

You should declare a method which have the same definition as WaitCallback delegate. You can use the following code snippet:

ThreadPool.QueueUserWorkItem(Multiply, new object[] { 2, 3 }); 

public static void Multiply(object state)
{
    object[] array = state as object[];
    int x = Convert.ToInt32(array[0]);
    int y = Convert.ToInt32(array[1]);
}

Anonymous delegate version is:

 ThreadPool.QueueUserWorkItem(delegate(object state)
    {
        object[] array = state as object[];
        int x = Convert.ToInt32(array[0]);
        int y = Convert.ToInt32(array[1]);
    }
    , new object[] { 2, 3 });

Upvotes: 42

Chris Dickson
Chris Dickson

Reputation: 12135

Here's a fuller example which gets the result back to the initial thread, and shows how the delegate can be defined anonymously:

class Program
{
    static void Main(string[] args)
    {
        using (MultiplyTask task = new MultiplyTask() { Multiplicands = new int[] { 2, 3 } })
        {
            WaitCallback cb = new WaitCallback(delegate(object x)
            {
                MultiplyTask theTask = x as MultiplyTask;
                theTask.Result = theTask.Multiplicands[0] * theTask.Multiplicands[1];
                theTask.Set();
            });
            ThreadPool.QueueUserWorkItem(cb, task);

            Console.WriteLine("Calculating...");
            if (task.WaitOne(1000))
            {
                Console.WriteLine("{0} times {1} equals {2}", task.Multiplicands[0], task.Multiplicands[1], task.Result);
            }
            else
            {
                Console.WriteLine("Timed out waiting for multiplication task to finish");
            }
        }
    }

    private class MultiplyTask : EventWaitHandle
    {
        internal MultiplyTask() : base(false, EventResetMode.ManualReset) { }
        public int[] Multiplicands;
        public int Result;
    }
}

Upvotes: 4

Related Questions