使用带有单个int参数的Action的Task.Factory.StartNew

时间:2015-10-15 10:47:50

标签: c#

在下面的代码中,我传递一个在StartNew之外声明的Action,看起来很好。

Action ac = () => { Console.WriteLine("Executing Action in Task 7!");  };
var t7 = Task.Factory.StartNew(ac  );
Task.WaitAny(t7);

但我想将一个int参数传递给action(我想在StartNew之外声明这个动作)。

Action<int> ac2 = (n) => 
{
     Console.WriteLine("Executing Action with 1 parameter = {0}", n);              
};
var t9 = Task.Factory.StartNew(  ac2  , 4); //Problem here????

以下代码也很好,但我不想以这种方式使用Action。我想在外面定义Action并在StartNew()中调用它,如上所述。如何使用ac2所以我得到与下面代码相同的结果。

var t8 = Task.Factory.StartNew(  (n) => 
{
    Console.WriteLine("Executing Action in Task 8!");
    Console.WriteLine("Param pass {0}", n);

}, 4 );
Task.WaitAny(t8);

4 个答案:

答案 0 :(得分:4)

不确定现有答案为何如此复杂:

Task.Factory.StartNew(() => ac(4));

这就是全部。只需调用包含在lambda中的函数即可。更好地使用Task.Run

Task.Run(() => ac(4));

StartNew能够采用另一个object参数,但这是一个非常专业的API,不必要地进行复杂处理,应该很少使用。它避免了两个小而短暂的对象的分配。不要使用它。

答案 1 :(得分:1)

您可以使用其他委托功能:

Func<Action<int>, int, Action> createDelegate = (action, arg) =>
{
    return () => action(arg);
};
Task.Factory.StartNew(createDelegate(ac2, 2));

答案 2 :(得分:0)

改为使用Action<object>

Action<object> ac2 = (n) => 
{
     Console.WriteLine("Executing Action with 1 parameter = {0}", n);              
};

var t9 = Task.Factory.StartNew(ac2, 4);

对于这种情况,StartNew()方法没有过载来接受Action<T>Action<int>。只允许Action<object>

答案 3 :(得分:0)

您可以使用接受object的重载来发送Tuple<T1, T2>

        Action<int> ac2 = (n) =>
        {
            Console.WriteLine("Executing Action with 1 parameter = {0}", n);            
        };

        var _data = new Tuple<Action<int>, int>(ac2, 4);

        var t9 = Task.Factory.StartNew((obj) =>
            {
                var data = obj as Tuple<Action<int>, int>;
                data.Item1(data.Item2);
            }, _data);