[英]Locking main() thread
此处的术语不确定,但我基本上可以使用我的应用程序的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<string> value1 = new List<String> { "01020402", "test" };
valuechange = new RegistryValueChange(hiveid, key1, value1);
valuechange.RegistryValueChanged += new EventHandler<RegistryValueChangedEventArgs>(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文件和change事件,以便保留活。
尝试将其构建到Windows服务中 。
该线程包含两个从Windows服务中查找登录用户的建议,但是我不确定它们是否有效。
如您所料, Main()
方法正在终止,因为执行从Join()
方法流出后又回到了主线程,然后终止。
在方法TimerMeth()
和start()
放置循环,或者更适当地将应用程序重新设计为Windows Service(如zac所说)。
您有几个问题。
您的第一个线程只是创建一个计时器(它将启动另一个线程)。 该线程很快终止,使您对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
在哪里定义?
您的方法将运行一次,然后线程将退出。 没有什么可以让它们继续运行。
尝试这个:
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#线程电子书 。
为了使主线程保持活动状态,最简单的方法之一是在主函数的末尾添加以下行:
Thread.Sleep(Timeout.Infinite);
当您的ThreadStart
函数返回时,该Thread
将终止,这允许主线程在Join()
之后继续。 由于您只是在设置要触发的计时器,因此该方法将很快返回。 您需要提供某种锁,以防止应用程序退出。
另外,看起来您根本不需要使用线程来完成您要尝试的工作。 而是使用Timer
并提供锁以防止Main()
终止。
在我看来,您的所有功能都已完成? 也就是说,它们都“跌出谷底”。 一旦所有功能运行完毕,您就无事可做了,您的应用程序将关闭。 您想在main中运行某种循环。
您还需要查看计时器。 我怀疑它目前正在被垃圾收集。 您可以在函数范围内创建它,但是该函数已被保留,因此不再引用您的计时器,它将被收集。 您的计时器必须是root。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.