0

这篇文章是Way to quick show/hide WinForms GUI C#的延续,因为在这种特殊情况下它对我不起作用。

我有两个问题:

  • 1是mainAnnounceWindow gui应该开始隐藏,然后在被调用时: windowStateChange("Show") 它应该显示,通过 windowStateChange("Hide") 它应该隐藏。它不能正确地做到这一点,因为当我启动应用程序时它可以看到 0.5 秒(我看到它在闪烁)。有没有办法让它开始隐藏而不闪烁半秒钟。

  • 2是从myThreadHandler(Queue.Work)调用时windowStateChange不能正常工作。

    internal class Program {
    public delegate void StateCallBack(string varState);
    public static readonly Announce mainAnnounceWindow = new Announce();
    public static readonly Thread myThreadGuiAnnounce = new Thread(showGuiAnnounce);
    public static readonly Thread myThreadTcpClient = new Thread(threadTcpClient);
    public static readonly Thread myThreadUdpMonitor = new Thread(threadUdpMonitor);
    public static readonly Thread myThreadHandler = new Thread(Queue.work);
    
    public static void Main() 
    {
        myThreadGuiAnnounce.Start();
        myThreadTcpClient.Start();
        myThreadUdpMonitor.Start();
        myThreadHandler.Start();
        windowStateChange("Hide");
    
        while (true) {
            Thread.Sleep(1000);
        }
    }
    public static void windowStateChange(string varState) {
        if (mainAnnounceWindow.InvokeRequired) {
            mainAnnounceWindow.Invoke(new StateCallBack(windowStateChange), new object[] {varState});
        } else {
            if (varState == "Hide") {
                mainAnnounceWindow.Hide();
                mainAnnounceWindow.TopMost = false;
            } else {
                mainAnnounceWindow.Show();
                mainAnnounceWindow.TopMost = true;
            }
        }
    }
        private static void showGuiAnnounce() {
        mainAnnounceWindow.ShowDialog();
    
    }
    }
    

另一类:

  public class Queue : IDisposable {
 public static void work() {
        while (true) {
            string task = null;
            lock (locker)
                if (tasks.Count > 0) {
                    task = tasks.Dequeue();
                    if (task == null) {
                        return;
                    }
                }
            if (task != null) {
                //MessageBox.Show("Performing task: " + task);
                Program.mainAnnounceWindow.setLogTextBox(task);
                Program.mainAnnounceWindow.setLogTrayTip(task);
                Program.windowStateChange("Show");
                Thread.Sleep(5000); // simulate work...
                Program.windowStateChange("Hide");
            } else {
                wh.WaitOne(); // No more tasks - wait for a signal
            }
        }
    }

}

问题在于:

                Program.windowStateChange("Show");
                Thread.Sleep(5000); // simulate work...
                Program.windowStateChange("Hide");

当我调用 Program.windowStateChange("Show"); 从其他线程内部,gui显示但不完全......就像我可以看到它想显示,但它没有。就像一个应用程序的挂起。但是当 Thread.Sleep(5000) 通过应用程序隐藏。

来电:

                Program.mainAnnounceWindow.setLogTextBox(task);
                Program.mainAnnounceWindow.setLogTrayTip(task);

没有问题。BaloonTip 显示,只是 Gui 没有正确显示。我做错了什么。

哦,当然我做了一些剪切/粘贴,所以它可能会遗漏一些东西。如果有必要添加一些东西让我知道。

带着敬意,

愤怒的少年

4

2 回答 2

1

您的问题是您正在从非 ui 线程访问 ui 对象,这是不允许的。您需要将包装您想要执行的操作的委托传递给其中一个 ui 控件(可能是您的表单对象)上的 Invoke 或 BeginInvoke 方法。

于 2010-02-03T18:14:35.490 回答
1

问题是你的主线程被锁定了,因为你添加了这个:

while (true) { 
    Thread.Sleep(1000); 
} 

这将阻止窗口线程适当地接收和处理窗口消息(例如显示和隐藏)。

您还需要使用 mainAnnounceWindow.Show(), not mainAnnounceWindow.ShowDialog(),因为这会阻止控制正确返回到主线程。你应该只调用Application.Run(mainAnnounceWindow)你的 Main 例程:

public static void Main()       
{      
    myThreadGuiAnnounce.Start();      
    myThreadTcpClient.Start();      
    myThreadUdpMonitor.Start();      
    myThreadHandler.Start();      

    // Just change your main window's load to hide itself... windowStateChange("Hide");      
    Application.Run(mainAnnounceWindow);
}
于 2010-02-03T18:15:22.310 回答