C#multithreading控制台应用程序 – 控制台在线程完成之前退出
我有一个ac#console应用程序,最多可以创建5个线程。
线程执行正常,但UI线程在完成其工作时关闭。
有没有办法保持主UI线程运行,只要侧线程正在运行?
foreach (var url in urls) { Console.WriteLine("starting thread: " + url); ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(myMethod), url); }
我按照上面的代码开始了我的线程。
ThreadPool中的线程是后台线程,这意味着现有的应用程序不会等待它们完成。
你有几个选择:
- 等待例如信号量
- 等待Sleep()的计数器,非常粗糙,但对于一个简单的控制台应用程序是好的。
- 使用TPL,
Parallel.ForEach(urls, url => MyMethod(url));
如果您使用的是.NET 4.0:
var tasks = new List(); 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));
啊 – ThreadPool是背景。 它已排队,但随后您的程序结束。 成品。 程序终止。
读取信号量(WaitSignal)并等待 – 结束时回调中的线程信号结束,当所有信号都表明主线程可以继续时。
如果你正在使用.net 4那么:
urls.AsParallel().ForAll(MyMethod);
在.net 4之前,然后启动单个线程,将它们保存在列表中并调用Join()。 工作人员不是背景的事实会在主线程退出后保持活着,但Join()更明确。
List workers = new List (); 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);
在返回/结束之前的main方法中:
while(ThreadsComplete < urls.Count) { Thread.Sleep(10); }
以上基本上是一个WaitForAll同步方法。
在主要:
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(); } }
- System.Net.Mail和=?utf-8?B?XXXXX …标题
- 为什么IEnumerable.Count()重新评估查询?
- System.ServiceModel.CommunicationException:基础连接已关闭
- 使用SerializableDynamicObject进行动态排序
- FluentValidation – validation包含Object列表的View Model
- 如何使用ADAL,NetStandard和Azure AD在没有提示CRM Dynamics Online Web服务的情况下进行身份validation
- 如何创建一个可以将键发送到控件而不会失去焦点的按钮 – 虚拟键盘
- 如果您点击或点击通知图标,如何获得不同的上下文菜单?
- 如何阻止ValueInjecter映射空值?