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);
}
按照上面的代码,我启动了我的线程。
线程池中的线程是后台线程,这意味着现有的应用程序不会等待它们完成。
你有几个选择:
- 等待信号量
- 使用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();
}
}