C# - ThreadPool QueueUserWorkItem Use?

71,531

Solution 1

The answer for your question depends on how you design the application. Do you put it inside a common project ? you dont want to overhead a simple operations.

But, You could create a generic call for ThreadPool QueueUserItem that receive params, 1 param, 2 param, etc.. This is good instead of sending a simple string and be restricted.

This how you impl a parameters QueueUserItem with WaitCallback:

ThreadPool.QueueUserWorkItem(
  new WaitCallback(delegate(object state)
  { YourMethod(Param1, Param2, Param3); }), null);

taken from C# Execute Method (with Parameters) with ThreadPool

And some links for ideas:
http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
Generic ThreadPool in .NET
Difference between delegate.BeginInvoke and using ThreadPool threads in C#

Solution 2

I'm not entirely sure what kind of syntax you're looking for, but if you don't like the unused a in your example, why not use Task instead?

Task.Run(() => doStuff("hello world"));

It doesn't really seem a lot better, but at least it doesn't have an unused identifier.

Note: Task.Run() is .Net 4.5 or later. If you're using .Net 4 you have to do:

Task.Factory.StartNew(() => doStuff("hello world"));

which isn't as short.

Both of the above do use the thread pool.

If you really must avoid using a lambda, you can use an anonymous delegate (which @nowhewhomustnotbenamed already mentioned):

Task.Run(delegate { doStuff("Hello, World!"); });

But what's the point of that? It's much less readable!

Solution 3

What about this?

class Program
{
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(MyWork, "text");
        Console.ReadKey();
    }

    private static void MyWork(object argument)
    {
        Console.WriteLine("Argument: " + argument);
    }
}

Or if you do not want to be signature restrictive and have a simple way of putting methods on a thread you can do it like this.For methods that do and do not return a value and have up to 6 parameters it would require you to define 12 overloads if I am not mistaken. It requires a bit more work up front, but is more simple to use.

class Program
{
    static void Main(string[] args)
    {
        var myClass = new MyClass();
        myClass.DoWork();
        Console.ReadKey();
    }
}

public static class ObjectThreadExtension
{
    public static void OnThread(this object @object, Action action)
    {
        ThreadPool.QueueUserWorkItem(state =>
        {
            action();
        });
    }

    public static void OnThread<T>(this object @object, Action<T> action, T argument)
    {
        ThreadPool.QueueUserWorkItem(state =>
        {
            action(argument);
        });
    }
}

public class MyClass
{
    private void MyMethod()
    {
        Console.WriteLine("I could have been put on a thread if you like.");
    }

    private void MySecondMethod(string argument)
    {
        Console.WriteLine(argument);
    }

    public void DoWork()
    {
        this.OnThread(MyMethod);
        this.OnThread(MySecondMethod, "My argument");
    }
}
Share:
71,531
Bitterblue
Author by

Bitterblue

Since Stackoverflow sucks, I'm gonna be egoistic and only look for answers. No more help from me. Thanks! Bye!

Updated on September 10, 2020

Comments

  • Bitterblue
    Bitterblue over 3 years

    Just right now I'm using following code to add queued threads. I don't like it. And my colleagues won't either because they don't know C# very well. All I want is of course to queue a method to be executed in a new thread.

    private static void doStuff(string parameter)
    {
        // does stuff
    }
    
    // call (a)
    ThreadPool.QueueUserWorkItem(a => doStuff("hello world"));
    // call (b)
    ThreadPool.QueueUserWorkItem(delegate { doStuff("hello world"); });
    

    So are there other use variations of ThreadPool.QueueUserWorkItem ?

    Best would be another 1-Line-Call. If possible with use of Func<> or Action<>.


    EDIT: Got (b) from the answers and comments and I like it better already.

  • Bitterblue
    Bitterblue almost 11 years
    Actually I want to avoid the Lambda thing.
  • Bitterblue
    Bitterblue almost 11 years
    Would that also be possible with Func or Action or without the extra call body ?
  • Matthew Watson
    Matthew Watson almost 11 years
    @mini-me Well I added an example which avoids using a lambda... It's worse tho, IMO.
  • ilansch
    ilansch almost 11 years
    It will be possible, When you build the WaitCallback, dont send a simple "delegate", send your own delegate instead. but, how do you expect to get the result back ? usually when sending operation to worker thread, you dont expect to get a result, only to make sure the job is done. You can achieve this by implementing a async pattern. c-sharpcorner.com/UploadFile/rmcochran/…
  • bytedev
    bytedev about 10 years
    @mini-me Lambda expressions pretty much replaced anonymous delegates quite a while ago. So you would do well to get used to them sooner rather than later.
  • Bitterblue
    Bitterblue about 7 years
    This would be a winner for me, if it wasn't signature restrictive like that. But still kinda cool to just give it a method and be done with it.
  • Mike de Klerk
    Mike de Klerk about 7 years
    @Bitterblue I've added a second approach. A bit more work up front, but most easy in usage in my opinion.