2014-03-13 118 views
2

我试图在执行它们之前构建任务列表。这里有一些示例代码:c#在执行之前构建任务列表

public string Returnastring(string b) 
    { 
     return b; 
    } 

    public string Returnanotherstring(string a) 
    { 
     return a; 
    } 


    private void btnT_Click(object sender, EventArgs e) 
    { 
     bool cont = true; 

     var Returnastringtask = Task.Factory.StartNew(() => Returnastring("hi")); 
     var Returnanotherstringtask = Task.Factory.StartNew(() => Returnanotherstring("bye")); 

     if (cont) 
     { 
      Task.WaitAll(new Task[] { Returnastringtask }); 
     } 
     else 
     { 
      Task.WaitAll(new Task[] { Returnanotherstringtask }); 
     } 

我知道这段代码并不像我期望的那样运行两个任务。我想基本上创建任务,然后执行一个或另一个基于布尔。我不想在真或假的条件下创建任务,因为我想避免代码复制。通过这个我的意思是如果cont是真的我可能想运行任务1,2,3,4,但如果cont是假的,我可能想要运行任务2,3,7,8。

+0

你的代码就像现在这样有点奇怪。您正在创建并启动这两项任务,但只能根据if语句等待一个或另一个任务。当直接调用基于if语句的方法会好很多时,这里似乎有很多工作。你真的想在这里获得什么? – Enigmativity

回答

5

而不是使用Task.Factory.StartNew创建任务(线索是这个名字),而不是仅仅通过new Task(...)与lambda表达式创建它们,然后只需使用taskName.Start()要开始他们的条件里面的。

1

您可以根据标志创建一个Action的数组,然后使用Parallel.Invoke()并行运行数组中的所有操作并等待它们完成。

如果需要,您可以使用lambdas作为允许您将其返回值分配给本地变量的操作。

下面是一个完整的可编译示例。与getFlag()它返回false返回true再次尝试:

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApp1 
{ 
    sealed class Program 
    { 
     void run() 
     { 
      bool flag = getFlag(); 
      var results = new string[5]; 
      Action[] actions; 

      if (flag) 
      { 
       actions = new Action[] 
       { 
        () => results[0] = function("f1"), 
        () => results[1] = function("f2"), 
        () => results[2] = function("f3") 
       }; 
      } 
      else 
      { 
       actions = new Action[] 
       { 
        () => results[3] = function("f4"), 
        () => results[4] = function("f5") 
       }; 
      } 

      Parallel.Invoke(actions); // No tasks are run until you call this. 

      for (int i = 0; i < results.Length; ++i) 
       Console.WriteLine("Result {0} = {1}", i, results[i]); 
     } 

     private bool getFlag() 
     { 
      return true; // Also try with this returning false. 
     } 

     string function(string param) 
     { 
      Thread.Sleep(100); // Simulate work. 
      return param; 
     } 

     static void Main(string[] args) 
     { 
      new Program().run(); 
     } 
    } 
} 
0

的Task.Factory.StartNew将真正开始你的任务。你想设置任务,然后根据一些逻辑运行它们。

您可以在任何地方构建任务,但应在逻辑之后启动它们。这个例子在逻辑之后构建它们。

也许你可以像这样运行:

If(A) 
{ 
    doA(); 
} 
Else 
{ 
    doB(); 
} 

然后开始调用的功能等里面你的任务:

public void doA() 
{ 
    for (int i = 0; i < NumberOfTasks; i++) 
    { 
      tasks[i] = Task.Factory.StartNew(() => 
      { 
       try 
       { 
        //enter tasks here 
        // i.e. task 1, 2, 3, 4 
       } 
      } 
    }, token); 

    Task.WaitAll(tasks);  
} 
5

那么,另一种方法,(我觉得这非常直接的)

 var list = new List<Task>(); 
     for (var i = 0; i < 10; ++i) 
     { 
      var i2 = i; 
      var t = new Task(() => 
       { 
        Thread.Sleep(100); 
        Console.WriteLine(i2); 
       }); 
      list.Add(t); 
      t.Start(); 
     } 

     Task.WaitAll(list.ToArray()); 
相关问题