【问题标题】:Stop to finish all threads before starting new threads c# 4.0在启动新线程之前停止以完成所有线程 c# 4.0
【发布时间】:2015-02-12 19:01:56
【问题描述】:

我正在使用以下方法创建许多线程

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());

        });
    }

【问题讨论】:

  • 尝试使用 CountdownEvent 类msdn.microsoft.com/en-us/library/…
  • 那么,你想要两种类型的任务:第一种可以并发运行,第二种应该独占运行?
  • 我希望当我调用一个方法假设 methodA() 时,它应该检查是否有任何线程在运行。它会等待完成正在运行的线程,但在两者之间,如果有任何新请求来创建相同的新线程,则使用 Task.Factory.StartNew 它应该等待并且不会丢失。

标签: c# multithreading


【解决方案1】:

我认为您真正想要的是实现某种在单个线程中执行工作的队列。这是一些最小的实现(未经测试!)

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();
    }
}

【讨论】:

  • 感谢您的回复。我已经编辑了我的问题。你能在这里建议吗?
【解决方案2】:

我自己解决了这个问题,方法是将创建的任务存储到列表中并对其应用锁定。

 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);
                }
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多