C# - ThreadPool QueueUserWorkItem Использовать?
прямо сейчас я использую следующий код для добавления потоков в очереди. Мне это не нравится. И мои коллеги тоже не будут, потому что они не очень хорошо знают C#. Все, что я хочу, это, конечно, очередь метода для выполнения в новом потоке.
private static void doStuff(string parameter)
{
// does stuff
}
// call (a)
ThreadPool.QueueUserWorkItem(a => doStuff("hello world"));
// call (b)
ThreadPool.QueueUserWorkItem(delegate { doStuff("hello world"); });
так есть другие варианты использования ThreadPool.QueueUserWorkItem
?
лучше всего будет еще один 1-Line-Call. По возможности с использованием Func<>
или Action<>
.
EDIT: получил (b) из ответов и комментарии, и мне это уже больше нравится.
3 ответов
ответ на ваш вопрос зависит от того, как вы проектируете приложение. Вы помещаете его в общий проект ? вы не хотите накладывать расходы на простые операции.
но вы можете создать общий вызов для ThreadPool QueueUserItem, который получает params, 1 param,2 param и т. д.. Это хорошо вместо того, чтобы отправить простую строку и быть ограниченным.
Это, как вы импл параметры QueueUserItem с WaitCallback:
ThreadPool.QueueUserWorkItem(
new WaitCallback(delegate(object state)
{ YourMethod(Param1, Param2, Param3); }), null);
принято от C# Выполнить метод (с параметрами) с ThreadPool
и некоторые ссылки для ideas:
http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
общий ThreadPool в .NET
разница между делегатами.BeginInvoke и использование потоков ThreadPool в C#
Я не совсем уверен, какой синтаксис вы ищете, но если вам не нравится неиспользованные a
в вашем примере, почему бы не использовать ?
Task.Run(() => doStuff("hello world"));
на самом деле это не кажется намного лучше, но, по крайней мере, у него нет неиспользуемого идентификатора.
Примечание: Task.Run()
является .Net 4.5 или более поздней версии. Если вы используете .Net 4, вам нужно сделать:
Task.Factory.StartNew(() => doStuff("hello world"));
что не так коротка.
оба из вышеперечисленных используют пул потоков.
если вы действительно должны избегать использования лямбды, вы можете использовать анонимный делегат (который @nowhewhomustnotbenamed уже упоминался):
Task.Run(delegate { doStuff("Hello, World!"); });
но какой в этом смысл? Это гораздо менее читабельно!
Как насчет этого?
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(MyWork, "text");
Console.ReadKey();
}
private static void MyWork(object argument)
{
Console.WriteLine("Argument: " + argument);
}
}
или если вы не хотите ограничивать подпись и иметь простой способ размещения методов в потоке, вы можете сделать это так.Для методов, которые возвращают и не возвращают значение и имеют до 6 параметров, вам потребуется определить 12 перегрузок, если я не ошибаюсь. Он требует немного больше работы спереди, но более прост в использовании.
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");
}
}