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

本文关键字:控制台 退出 多线程 应用程序 线程 | 更新日期: 2023-09-27 18:11:07

我有一个c#控制台应用程序,它创建了多达5个线程。

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

是否有一种方法来保持主UI线程运行,只要副线程正在运行?

foreach (var url in urls)
{
    Console.WriteLine("starting thread: " + url); 
    ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(myMethod), url);
}
按照上面的代码,我启动了我的线程。

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

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

你有几个选择:

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

如果您使用的是。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));

啊——线程池是后台的。它是排队的,但随后程序就结束了。完成了。程序终止。

阅读Semaphores (WaitSignal)和wait-在回调结束时,当所有线程都表示主线程可以继续时,回调中的线程发出结束信号。

如果你使用的是。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();
        }

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

在你的程序类中:

static volatile int ThreadsComplete = 0;

在你的"myMethod"结尾返回前:

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

在主方法返回/结束之前:

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

上面的代码实际上是拼凑了一个WaitForAll同步方法。

in Main:

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