簡體   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