C#多线程控制台应用程序 - 控制台在线程完成之前退出

时间:2011-10-13 18:52:42

标签: c# multithreading

我有一个c#控制台应用程序,最多可以创建5个线程。

线程执行正常,但UI线程在完成工作时关闭。

有没有办法让主UI线程保持运行,只要副线程正在运行?

foreach (var url in urls)
{
    Console.WriteLine("starting thread: " + url); 
    ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(myMethod), url);
}

我按照上面的代码开始我的线程。

6 个答案:

答案 0 :(得分:9)

ThreadPool中的线程是后台线程,这意味着现有的应用程序不会等待它们完成。

您有几个选择:

  • 等待例如信号量
  • 等待Sleep()的计数器,非常粗糙,但对于一个简单的控制台应用程序来说还可以。
  • 使用TPL,Parallel.ForEach(urls, url => MyMethod(url));

答案 1 :(得分:7)

如果您使用的是.NET 4.0:

var tasks = new List<Task>();

foreach(var url in urls)
{
    tasks.Add(Task.Factory.StartNew(myMethod, url));
}

// do other stuff...

// On shutdown, give yourself X number of seconds to wait for them to complete...
Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(30));

答案 2 :(得分:2)

啊 - ThreadPool是后台。它已排队,但随后您的程序结束。成品。程序终止。

读取信号量(WaitSignal)并等待 - 结束时回调中的线程信号结束,当所有信号都表明主线程可以继续时。

答案 3 :(得分:1)

如果你正在使用.net 4,那么:

urls.AsParallel().ForAll(MyMethod);

在.net 4之前,然后启动单个线程,将它们保存在列表中并调用Join()。工作人员不是背景的事实会在主线程退出后保持活着,但Join()更明确。

        List<Thread> workers = new List<Thread>();
        foreach(var url in urls)
        {
            Thread t = new Thread(MyMethod) {IsBackground = false};
            workers.Add(t);
            t.Start(url);
        }

        foreach (var worker in workers)
        {
            worker.Join();
        }

答案 4 :(得分:0)

最简单的解决问题的方法。

在您的课程班中:

static volatile int ThreadsComplete = 0;

在返回结束时的“myMethod”中:

//ThreadsComplete++; //*edit* for safety's sake
Interlocked.Increment(ref ThreadsComplete);

在你的main方法返回/结束之前:

while(ThreadsComplete < urls.Count) { Thread.Sleep(10); }

以上基本上是一个WaitForAll同步方法。

答案 5 :(得分:-1)

主页中的

var m = new ManualResetEvent(false);
// do something
foreach (var url in urls)
{
  Console.WriteLine("starting thread: " + url); 
  ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(myMethod), url);
}
m.WaitOne();


private static void myMethod(object obj)
{
  try{
   // do smt
  }
  finally {
    m.Set();
  }
}