2015-02-12 91 views
0

我使用下面的方法停止到启动新的线程C#4.0

Task.Factory.StartNew(() => 
          { 
          //do some task here 
          }); 

在某个时间点创建多个线程之前完成所有的线程我想执行的方法,但在此之前,我想

  1. 确保所有当前正在运行的线程都已完成。
  2. 确保是否有任何呼叫创建新线程应等待,不会丢失。
  3. 我的方法执行后,启动所有等待的线程。

任何好的解决方案,将不胜感激。

在此先感谢

--------------------编辑代码----------------- ------

for (int i = 0; i < 10; i++) 
    { 
     Task.Factory.StartNew(() => 
     { 
      Console.WriteLine("First Thread @ " + DateTime.Now.ToString()); 

     }); 
    } 

当我们到达这个调用这个执行

Console.WriteLine前,应检查任何未决的任务(“************** *****称为另一种方法***********************“);

当上面的代码被执行时,另一个请求和下面的代码一样,那么它只能在上面的代码行(在我的方法中)执行后才启动。

for (int i = 0; i < 10; i++) 
    { 
     Task.Factory.StartNew(() => 
     { 
      Console.WriteLine("Second Thread @ " + DateTime.Now.ToString()); 

     }); 
    } 
+0

尝试https://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx – BoldAsLove 2015-02-12 05:31:09

+0

https://msdn.microsoft.com/ en-us/library/95hbf2ta%28v = vs.110%29.aspx – mhs 2015-02-12 05:32:51

+0

所以,你想要有两种类型的任务:第一种类型可以同时运行,第二种类型应该独占运行? – PetSerAl 2015-02-12 05:41:31

回答

0

我想你真正想要的是实现某种队列,在一个线程中执行工作。下面是一些最小的实现(未经测试!)

class QueuedWorker 
{ 
    ConcurrentQueue<Action> queue = new ConcurrentQueue<Action>(); 
    ManualResetEvent waiter = new ManualResetEvent(false); 
    Thread workerThread; 

    public QueuedWorker() 
    { 
     workerThread = new Thread(ThreadWorker); 
     workerThread.Start(); 
    } 

    private void ThreadWorker() 
    { 
     Action nextTask; 

     while(true) 
     {  
      while(queue.TryDequeue(out nextTask)) 
      { 
       // run the queued task 
       nextTask(); 
      } 

      waiter.WaitOne(); 
      waiter.Reset(); 
     } 
    } 

    public void Enqueue(Action item) 
    { 
     queue.Enqueue(item); 
     waiter.Set(); 
    } 
} 
+0

感谢您的回复。我编辑了我的问题。你能在这里建议吗? – 2015-02-12 08:38:46

0

我通过存储创建成一个列表的任务,并在其上应用锁解决了这个问题我自己。使用CountdownEvent类

class Program 
     { 
      static List<Task> taskList = new List<Task>(); 

      static void Main(string[] args) 
      { 
       Task.Factory.StartNew(() => { StartTasks("First"); }); 
       Task.Factory.StartNew(() => { LoadMethod(); }); 
       Task.Factory.StartNew(() => { StartTasks("Second"); StartTasks("Third"); }); 
       Task.Factory.StartNew(() => { LoadMethod(); }); 
       Task.Factory.StartNew(() => { StartTasks("Four"); }); 
       Task.Factory.StartNew(() => { LoadMethod(); }); 
       Task.Factory.StartNew(() => { StartTasks("Five"); StartTasks("Six"); StartTasks("Seven"); StartTasks("Eight"); }); 
       Task.Factory.StartNew(() => { LoadMethod(); }); 
       Task.Factory.StartNew(() => { StartTasks("Nine"); StartTasks("Ten"); }); 
       Task.Factory.StartNew(() => { LoadMethod(); }); 

       Console.WriteLine("Execution is completed !"); 
       Console.ReadKey(); 
      } 

      public static void LoadMethod() 
      { 
       // Lock and wait to not allow any thead to modify the list 
       lock (taskList) 
       { 
        if (taskList.Any()) 
        { 
         Task.WaitAll(taskList.ToArray()); 
        } 

        Debug.WriteLine("*******************Called Another Method***********************"); 
        taskList.Clear(); 
       } 
      } 

      public static void StartTasks(string taskName) 
      { 
       lock (taskList) 
       { 
        for (int i = 0; i < 10; i++) 
        { 
         var t = new Task(() => 
         { 
          Debug.WriteLine(taskName + " @ " + DateTime.Now.ToString()); 
          //System.Threading.Thread.Sleep(500); 
         }); 
         taskList.Add(t); 
        } 

        Task.Factory.StartNew(() => taskList.ForEach(task => 
        { 
         if (task.Status == TaskStatus.Created) 
         { 
          task.Start(); 
         } 
        }), TaskCreationOptions.AttachedToParent); 
       } 
      } 
     }