锁定main()线程

时间:2009-11-12 15:16:29

标签: c# multithreading

这里的术语不完全确定,但在这里我基本上我的应用程序的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文件和更改活着的事件。

7 个答案:

答案 0 :(得分:2)

尝试将其构建为windows service

这个thread包含两个从Windows服务中查找登录用户的建议,但我不确定它们是否有效。

答案 1 :(得分:2)

正如您所料,Main()方法正在终止,因为执行从Join()方法流回到主线程,然后终止。

在方法TimerMeth()start()中放置循环,或者更恰当地将应用程序重新设计到Windows服务中(如zac所说)。

答案 2 :(得分:2)

你有几个问题。

你的第一个线程只是创建一个计时器(启动另一个线程)。这个帖子很快就会终止,让你对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定义在哪里?

答案 3 :(得分:1)

您的方法将运行一次,然后线程将退出。什么都没有让他们继续运转。

试试这个:

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的Free C# Threading E-Book

答案 4 :(得分:1)

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

Thread.Sleep(Timeout.Infinite);

答案 5 :(得分:0)

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

此外,看起来你根本不需要使用线程来做你正在尝试的事情。相反,只需使用Timer并提供锁定即可使Main()无法终止。

答案 6 :(得分:0)

在我看来,您的所有功能都在完成?也就是说,它们都“落到了底层”。一旦所有功能都运行完毕,就没有什么可做的了,你的应用就会关闭。你想在main中运行某种循环。

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