锁定main()线程
不完全确定这里的术语,但在这里我基本上我有我的应用程序的main()线程启动并调用两个线程,一个设置一个事件处理程序等待特定的注册表项更改,而另一个启动一个计时器每5分钟左右写一次对xml文件所做的更改并连续运行。 我遇到的问题是,一旦调用了两个被调用的方法,它就会返回main并结束程序。 我的相关代码部分可以在下面找到,所以任何帮助将不胜感激:
static void Main(string[] args) { runner one = new runner(); runner two = new runner(); Thread thread1 = new Thread(new ThreadStart(one.TimerMeth)); Thread thread2 = new Thread(new ThreadStart(two.start)); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); } public void TimerMeth() { System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); timer.Interval = 300000; timer.Enabled = true; } private void OnElapsedTime(object source, ElapsedEventArgs e) { file write = new file(); write.write(RegKeys); } public void start() { if (File.Exists("C:\\test.xml")) { file load = new file(); RegKeys = load.read(RegKeys); } string hiveid = "HKEY_USERS"; WindowsIdentity identity = WindowsIdentity.GetCurrent(); string id = identity.User.ToString(); string key1 = id + "\\\\Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Windows Messaging Subsystem\\\\Profiles\\\\Outlook\\\\0a0d020000000000c000000000000046"; List value1 = new List { "01020402", "test" }; valuechange = new RegistryValueChange(hiveid, key1, value1); valuechange.RegistryValueChanged += new EventHandler(valuechange_RegistryValueChanged); try { valuechange.Start(); } catch { StreamWriter ut; ut = File.AppendText("C:\\test.txt"); ut.WriteLine("error occured in starting management"); ut.Close(); } file test = new file(); test.checkfile("C:\\test.xml"); } void valuechange_RegistryValueChanged(object sender, RegistryValueChangedEventArgs e) { // deals with the returned values }
基本上所有的代码工作正常我已经在Windows窗体应用程序中测试它但现在我需要在一个独立的应用程序中运行它,在后台没有接口,需要它继续写入xml文件和更改事件保持活。
您的方法将运行一次,然后线程将退出。 什么都没有让他们继续运行。
试试这个:
thread1.IsBackground = true; thread2.IsBackground = true; public void start() { while(true) { // ... do stuff Thread.Sleep(1000*60*5) // sleep for 5 minutes } } public void TimerMeth() { while(true) { file write = new file(); write.write(RegKeys); Thread.Sleep(30000); } }
正如其他海报所述,您还需要确保您的主要方法不会退出。 使应用程序成为Windows服务似乎是在您的情况下解决此问题的好方法。
您可能还希望在线程上处理ThreadInterruptedException和ThreadAbortException 。
如果你真的想深入了解线程的细节,请查看Joe Albahari的免费C#Threading电子书 。
正如您所料, Main()
方法正在终止,因为执行从Join()
方法流回主线程,然后终止。
在TimerMeth()
和start()
方法中放置循环,或者更恰当地将应用程序重新设计到Windows服务中(如zac所述)。
你有几个问题。
你的第一个线程只是创建一个计时器(启动另一个线程)。 这个post很快就会终止,让你对Join
的调用毫无意义。 这个线程应该做的是实际进行等待和检查。 您可以像这样轻松调整代码:
public void TimerMeth() { System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); timer.Interval = 300000; timer.Enabled = true; try { while(true) { OnElapsedTime(null, null); // you should change the signature Thread.Sleep(30000); } } catch(ThreadAbortException) { OnElapsedTime(null, null); throw; } }
显然你应该改变OnElapsedTime
的签名来消除参数,因为这里没有使用它们。
我有一种感觉,文件处理的方式有些不对,但鉴于我不明白该代码的作用 ,我将不会发表评论。 究竟什么是文件的目的? RegKeys
在哪里定义?
尝试将其构建到Windows服务中 。
此线程包含两个从Windows服务查找登录用户的建议,但我不确定它们是否有效。
ThreadStart
函数返回时Thread
将终止,这允许主线程在Join()
之后继续。 由于您只是设置一个计时器来启动,因此该方法将非常快速地返回。 您需要提供某种锁以防止您的应用程序退出。
此外,看起来你根本不需要使用线程来做你正在尝试的事情。 相反,只需使用Timer
并提供锁定以防止Main()
终止。
在我看来,你的所有function都在完成? 也就是说,它们都“落到了底层”。 一旦所有function都运行完毕,就没有什么可做的了,你的应用就会关闭。 你想在main中运行某种循环。
您还需要查看您的计时器。 我怀疑它目前正在被垃圾收集。 您可以在函数范围内创建它,但该函数正在保留,因此不再引用您的计时器,它将被收集。 你的计时器需要是一个根。