显示表单会锁定单声道

时间:2011-07-14 20:39:25

标签: c# macos mono

我有一个用c#编写的单声道应用程序,并使用“mono myapp.exe”在Mac上执行

从项目属性中查看时,应用程序本身是一个“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()显示它,然后在30秒后,表单上的计时器运行Close(),然后frm被释放。但是,当发生这种情况时,在我的Mac上,我看到一个应用程序标题栏上显示“mono”和我的停靠栏上的单个应用程序的新图标。约2分钟后,活动监视器中的单声道进程显示“无响应”。这最终将阻止用户注销,关闭等(因为Mac OS无法正常杀死单声道)。

另一方面......如果服务器从不告诉进程显示该表单,一切运行正常且花花公子:一个停靠图标永远不会显示(这很好!),单声道标题栏永远不会显示和单声道进程继续愉快地运行,而不是阻止系统关闭或重新启动。

任何人都经历过这个或有关于它的原因的想法?我的猜测是,这是一个由表单创建的新GUI线程,它永远不会被关闭,并以某种方式导致锁定,但我不确定如何处理它。

感谢您的任何建议。

更新

这里有一些代码可以轻松复制并看到这种情况。我意识到这似乎是“非标准的”。话虽如此,下面的内容在Windows环境中完美运行,并提供了在显示消息时除非在任务区域中显示图标所需的结果。目前,使用Application.Run并简单地执行frm.ShowDialog()会产生完全相同的结果。

最后我们需要的是能够显示表单,然后从Dock中销毁表单和任何相关的图标。我怀疑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.
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我觉得我错过了几件事。最值得注意的是

 [STAThread]
 static void Main(string[] args) { //....

另请参阅此答案:Windows Forms and ShowDialog problem

答案 1 :(得分:1)

我看不到像为窗口应用程序初始化消息循环一样的东西。即在Windows窗体中的情况类似于Application.Run()。如果你没有它,难怪应用程序冻结。无论如何,发布更多代码可能会有所帮助,如评论中所述。

答案 2 :(得分:0)

最后,我无法解决这个问题。我创建了一个启动另一个显示消息表单的应用程序的进程。不是真正的答案,而是我必须采用的解决方案。