[英]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.