2011-07-14 26 views
2

我有C#編寫的單應用程序,並在使用Mac「單程序myapp.exe」顯示形式鎖定了單

的應用程序本身執行的是「Windows應用程序」,從項目性質看,但它並不總是顯示一個窗口。在Program.cs中,有一個靜態Main:

static void Main(string[] args) { 
    UserClient client = new UserClient(); 
    client.Start(args); 
} 

public class UserClient { 
    public void Start(string[] args) { 
      // Talk to server, listen for instructions, etc. 
      .... 
      // Launch the "Stay Alive" thread 
      // Just a thread that Sleeps/Loops watching for an exit command; mainly used to keep the process alive 
    } 
} 

裏面的UserClient的Start方法,有一段代碼,不斷地監控這給它的指令做事的服務器。它所做的一件事是可選地使用Windows窗體顯示消息。

當服務器指示進程顯示消息時,它實例化一個窗體,使用frm.ShowDialog()顯示窗體,然後在窗體運行Close()之後的30秒後,窗體上的計時器將被處理。但是,當發生這種情況時,在我的Mac上,我看到一個應用程序標題欄顯示單聲道應用程序的「單聲道」和我的停靠欄上的一個新圖標。大約2分鐘後,Activity Monitor中的mono進程顯示「Not Responding」。這最終將防止用戶註銷,關閉等(因爲Mac OS不能正常地殺死單聲道)。

,另一方面......如果服務器從來沒有告訴的過程中顯示的形式,一切都正常運行和花花公子:停靠欄圖標一直沒有出現(!這是很好的),單標題欄一直沒有出現和單聲道進程繼續愉快地運行,不會阻止系統關閉或重新啓動。

任何人都會遇到這種情況,或對造成這種情況的想法有所瞭解?我的猜測是這是一個新的GUI線程正在創建的形式,從來沒有被關閉,並在某種程度上導致鎖定,但我不確定如何處理它。

感謝您的任何建議。

更新:

下面是一些代碼很容易繁殖,看到這種情況出現。我意識到這看起來有點「不規範」。話雖如此,下面在Windows環境中完美地工作,並提供除了顯示消息時在任務區域中不顯示圖標的所需結果。目前,使用Application.Run和簡單地做frm.ShowDialog()產生完全相同的結果。

最後,我們需要的是能夠顯示窗體,然後銷燬窗體和任何關聯的圖標從碼頭。我懷疑GUI正在啓動一個永遠不會處理的線程,這就是爲什麼dock圖標仍然存在。有沒有辦法確保GUI線程被照顧?

static class Program { 
    static void Main() {    
     StartupClass s = new StartupClass(); 
     s.start(); 
    } 
} 

public class StartupClass { 
    Thread stayAliveThread; 

    public void start() { 
     // Stay alive thread 
     stayAliveThread = new Thread(stayAliveLoop); 
     stayAliveThread.Start(); 

     // This shows a form and would normally be used to display temporary and brief messages to the user. Close the message and you'll see the undesired functionality. 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
     Application.Exit(); 
     Application.ExitThread(); 
    } 

    /// <summary> 
    /// Keep the app alive. 
    /// </summary> 
    private void stayAliveLoop() { 
     while (true) { 
      Thread.Sleep(10000); 
      // In the real project this method monitors the server and performs other tasks, only sometimes displaying a message. 
     } 
    } 
} 
+1

你真的應該能夠將這個作爲我在那裏看到的文字描述的一個非常簡短的例子。 (爲什麼?這將有助於極大地篩選關鍵位的愚蠢/無關緊要的建議;如果有太多未知數,Stacko常規人羣往往會學會閉嘴:這隻會導致風格中延長的評論線索:'是的,我知道,但它仍然不起作用';'哦,這是不適用的,因爲我用X的方式解決了它;'等等)一些代碼消除了噪音 – sehe

回答

0

最後,我無法解決這個問題。我創建了一個啓動另一個顯示消息表單的應用程序。不是真正的答案,但我必須解決的解決方案。

1

我看不到像初始化消息循環的窗口申請什麼。即在Windows窗體的情況下,像Application.Run()。如果你沒有它,怪不得應用程序凍結。無論如何,張貼更多的代碼可能會有所幫助,如評論中所述。

+0

事實上,沒有呼叫Application.Run()。至少在Windows中,這給了我們應用程序「感覺」像隱藏進程的期望效果,並且僅在顯示消息時顯示(在任務欄中)。 – bugfixr

+0

我不確定你的描述,但你可能直接從另一個線程直接調用ShowDialog和Close。你不應該這樣做 - 使用Invoke或BeginInvoke。 –