我有一个用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.
}
}
}
答案 0 :(得分:1)
我觉得我错过了几件事。最值得注意的是
[STAThread]
static void Main(string[] args) { //....
答案 1 :(得分:1)
我看不到像为窗口应用程序初始化消息循环一样的东西。即在Windows窗体中的情况类似于Application.Run()
。如果你没有它,难怪应用程序冻结。无论如何,发布更多代码可能会有所帮助,如评论中所述。
答案 2 :(得分:0)
最后,我无法解决这个问题。我创建了一个启动另一个显示消息表单的应用程序的进程。不是真正的答案,而是我必须采用的解决方案。