繁体   English   中英

锁定main()线程

[英]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服务似乎是解决此问题的好方法。

您可能还想在线程上处理ThreadInterruptedExceptionThreadAbortException

如果您真的想深入了解线程的精髓,请查看Joe Albahari撰写的这本免费C#线程电子书

为了使主线程保持活动状态,最简单的方法之一是在函数的末尾添加以下行:

Thread.Sleep(Timeout.Infinite);

当您的ThreadStart函数返回时,该Thread将终止,这允许主线程在Join()之后继续。 由于您只是在设置要触发的计时器,因此该方法将很快返回。 您需要提供某种锁,以防止应用程序退出。

另外,看起来您根本不需要使用线程来完成您要尝试的工作。 而是使用Timer并提供锁以防止Main()终止。

在我看来,您的所有功能都已完成? 也就是说,它们都“跌出谷底”。 一旦所有功能运行完毕,您就无事可做了,您的应用程序将关闭。 您想在main中运行某种循环。

您还需要查看计时器。 我怀疑它目前正在被垃圾收集。 您可以在函数范围内创建它,但是该函数已被保留,因此不再引用您的计时器,它将被收集。 您的计时器必须是root。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM