显示表单锁定单声道



我有一个用c#编写的mono应用程序,并使用"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(),然后处理form。然而,当这种情况发生时,在我的Mac上,我看到一个应用程序标题栏上写着"mono",并且我的dock栏上出现了一个单声道应用程序的新图标。大约2分钟后,Activity Monitor中的单声道进程显示为"未响应"。这最终将阻止用户退出,关闭等(因为Mac OS不能优雅地杀死mono)。

另一方面……如果服务器从不告诉进程显示该表单,一切都运行得很好:dock图标永远不会显示(这很好!),mono标题栏永远不会显示,mono进程继续愉快地运行,不会阻止系统关闭或重新启动。

有人经历过这种情况吗?或者有人知道是什么原因造成的吗?我的猜测是,这是一个新的GUI线程被创建的形式,从来没有被关闭,并以某种方式导致锁定,虽然我不确定如何处理它。

谢谢你的建议。

更新:

下面是一些代码,可以很容易地重现并查看发生的情况。我意识到这似乎有点"不标准"。话虽如此,下面的程序在Windows环境下完美地工作,并提供了在任务区域中不显示图标的预期结果,除非显示消息。目前,正在使用Application。运行和简单地执行from . 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.
        }
    }
}

我觉得我错过了几件事。最明显的是

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

也看这个答案:Windows窗体和ShowDialog问题

我看不到像初始化窗口应用程序的消息循环这样的东西。例如,在windows窗体的情况下,像Application.Run()。如果你没有它,难怪应用程序冻结。在任何情况下,发布更多的代码可能是有帮助的,正如在评论中所说的。

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

最新更新