2010-08-17 180 views
0

Hello。當Windows XP中的UI線程凍結時System.Timers.Timer凍結

您很可能已經知道,當用戶界面線程也凍結時,它會凍結其操作,這是因爲它們運行在同一個線程中。

這迫使我使用一個System.Timers.Timer,反過來如果用戶界面凍結Timer繼續運行其通常的過程就像什麼都沒有發生過。

那麼我的應用程序做了一個與IE瀏覽器的工作分配,並不時瀏覽一個網站的Javascript代碼糟糕的IE瀏覽器凍結。因此,也會凍結我的應用程序用戶界面以及所有應用程序,因爲我的應用程序中的所有內容都運行在相同的Thread上。爲了解決這個問題,我的應用程序不時地對IE進程進行一次簡單的檢查,看看它們是否仍在響應,如果它們沒有被終止,那麼在另一個線程上。

這種反作用在Windows 7 32位上運行完美,但是當我在Windows XP計算機上運行我的應用程序時,反作用沒有效果,可能是因爲我的System.Timers.Timer也在用戶界面凍結時凍結。這就像它不會在Windows 7

發生不應一旦其另一Thread執行發生下面是反作用過程

private System.Timers.Timer IEResponsiveCheckTimer = new System.Timers.Timer(); 

private void onLoad(object sender, EventArgs e) 
{ 
    this.IEResponsiveCheckTimer.Interval = 15000; 
    this.IEResponsiveCheckTimer.Elapsed += new System.Timers.ElapsedEventHandler(IEResponsiveCheck); 
    this.IEResponsiveCheckTimer.Start(); 
} 

private void IEResponsiveCheck(object sender, EventArgs e) 
{ 
    Thread t = new Thread(new ThreadStart(IEResponsiveChecker)); 
    t.Start(); 
} 

static void IEResponsiveChecker() 
{ 
    bool terminate = false; 
    foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) 
    { 
     if (exe.ProcessName.StartsWith("iexplore")) 
     { 
      if (exe.Responding == false) 
      { 
       terminate = true; 
       break; 
      } 
     } 
    } 
    if (terminate == true) 
    { 
     foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) 
     { 
      if (exe.ProcessName.StartsWith("iexplore")) 
       try { exe.Kill(); } 
       catch { } 
     } 
    } 
} 

這段代碼是非常簡單的代碼。我們有一個每15秒運行一次的Timers.Timer,一旦它的時間流逝,一個方法被執行,然後在另一個Thread上運行delegatedelegate,如果他沒有響應,該方法負責終止IE。

我怎樣才能得到這個代碼,像它可以運行在Windows 7

任何幫助表示讚賞在Windows XP上運行良好。

謝謝。

編輯:

我也嘗試了System.Threading.Timer相同的結果,在Windows 7的作品,但不能在Windows XP。

編輯:繼凱文·蓋爾建議:

我只用線程來運行我的反作用嘗試,我發現它是不是它的線程自認爲是行不通的。它的Process.Responding屬性在Windows XP中運行不正常。

新代碼:

private void onLoad(object sender, EventArgs e) 
{ 
    Thread t = new Thread(new ThreadStart(IEResponsiveChecker)); 
    t.Start(); 
} 

static void IEResponsiveChecker() 
{ 
    bool terminate = false; 
    foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) 
    { 
     if (exe.ProcessName.StartsWith("iexplore")) 
     { 
      if (exe.Responding == false) 
      { 
       terminate = true; 
       break; 
      } 
     } 
    } 
    if (terminate == true) 
    { 
     foreach (System.Diagnostics.Process exe in System.Diagnostics.Process.GetProcesses()) 
     { 
      if (exe.ProcessName.StartsWith("iexplore")) 
       try { exe.Kill(); } 
       catch { } 
     } 
    } 
    Thread.Sleep(15000); 
    IEResponsiveChecker(); 
} 

這樣線程每15秒運行於Windows 7和XP兩個。但是我認爲它不起作用的原因是因爲他在沒有響應時沒有關閉IE。

我發現他沒有關閉IE,因爲根據exe.Responding它解決了進程是否響應,在Windows 7中,他檢測到IE沒有響應,並且在Windows XP中它說IE正在響應儘管事實上並非如此。這就是爲什麼在XP線程沒有關閉IE瀏覽器,所以我認爲線程無法正常工作。

因此畢竟。問題是我如何才能找到過程iexplore.exe實際上是否響應或不使用Process.Responding屬性?

信息:酒店Process.Responding爲了知道該進程是否響應要求Process.MainWindowHandle屬性,它由於某種原因,根據這個代碼sample,在Windows 7中,物業存在,但不能在Windows XP中,有這麼Process.Responding也不適用於XP。任何人都知道解決方法?

後果:考慮到我自己的問題已經得到解答,我將授予一個負責任的人,真正幫助我找到真正的問題。該問題的問題繼續here

謝謝大家。

回答

4

爲什麼要使用定時器。只需啓動第二個線程並每隔15秒檢查一次。這會更簡單,開銷更低。

但是,如果你想保持定時器,也許System.Threading.Timer類可能會解決這個問題。

+0

我第二個專用線程的想法。如果'System.Threading.Timer'沒有遇到同樣的問題,我會感到驚訝。最後,它基本上是'System.Timers.Timer'的主幹。 – 2010-08-17 21:25:56

+0

我傾向於同意Threading.Timer這只是一些嘗試。 – 2010-08-17 21:29:11

+0

永遠不會受傷:) – 2010-08-17 21:34:37

1

Windows 7在處理系統資源(如從SQL中的表鎖定到行鎖定)中對線程安全進行了一些重大更改。您可能會看到某些系統資源的爭用,這些資源會在XP中阻止,但允許在Win7中進行多次訪問。鑑於此,定時器運行的線程並不重要,因爲所有線程都將阻塞在相同的資源上。

也許如果您檢測到在您的應用中發生了這種情況,您可能會彈出消息,提示用戶升級其操作系統。 :)

+0

@Jonh Bowen:這個應用程序將運行在大量運行XP的虛擬機中。它是在XP中工作的。沒有解決方法。 – 2010-08-18 00:26:12