C # - ThreadPool QueueUserWorkItem Use?

en ce moment j'utilise le code suivant pour ajouter des threads en file d'attente. Je ne l'aime pas. Et mes collègues non plus parce qu'ils ne connaissent pas très bien C#. Tout ce que je veux c'est bien sûr faire la queue pour qu'une méthode soit exécutée dans un nouveau 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"); });

Existe-t-il d'autres variantes d'utilisation de ThreadPool.QueueUserWorkItem ?

le mieux serait un autre appel d'une ligne. Si possible avec l'utilisation de Func<> ou Action<> .


EDIT: a Obtenu (b) à partir des réponses et des commentaires et des j'aime déjà mieux.
21
demandé sur Bitterblue 2013-07-02 11:33:39

3 réponses

la réponse à votre question dépend de la façon dont vous concevez la demande. Vous le mettez dans un projet commun ? vous ne voulez pas survoler une opération simple.

mais, vous pourriez créer un appel générique pour ThreadPool Queeuseritem qui reçoivent des params, 1 param, 2 param, etc.. C'est bien au lieu d'envoyer une simple chaîne de caractères et être restreint.

Ce la façon dont vous impl un des paramètres QueueUserItem avec WaitCallback:

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

extrait de C# Méthode Execute (avec Paramètres) avec pool de threads

et quelques liens pour des idées:

http://msdn.microsoft.com/en-us/library/4yd16hza.aspx

Générique En. net

différence entre délégué.BeginInvoke et l'utilisation de threads ThreadPool dans C#

15
répondu ilansch 2017-05-23 10:31:14

Je ne suis pas entièrement sûr du type de syntaxe que vous recherchez, mais si vous n'aimez pas le a non utilisé dans votre exemple, pourquoi ne pas utiliser Task à la place?

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

Il ne semble pas vraiment beaucoup mieux, mais au moins il n'a pas non utilisées identificateur.

Note: Task.Run() est .Net 4.5 ou une version ultérieure. Si vous utilisez .Net 4, vous devez faire:

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

qui n'est pas aussi court.

les deux ci-dessus utilisent le pool de filetage.

si vous devez vraiment éviter d'utiliser une lambda, vous pouvez utiliser un délégué anonyme (qui @nowhewhomustnotbenamed déjà mentionné):

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

mais à quoi ça sert? C'est beaucoup moins lisible!

15
répondu Matthew Watson 2013-07-02 08:57:41

et ça?

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

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

ou si vous ne voulez pas être restrictif de signature et avoir une façon simple de mettre des méthodes sur un thread, vous pouvez le faire comme ceci.Pour les méthodes qui font et ne renvoient pas une valeur et qui ont jusqu'à 6 Paramètres, il vous faudrait définir 12 surcharges si Je ne me trompe pas. Elle nécessite un peu plus de travail à l'avant, mais est plus simple à utiliser.

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");
    }
}
2
répondu Mike de Klerk 2017-05-02 10:53:03