Этот пост является продолжением Way to quickly show/hide WinForms GUI C#, так как он не работает для меня в данном конкретном случае.Скрыть/Показать Winforms GUI C# из другого потока
У меня есть 2 проблемы:
1 является то, что mainAnnounceWindow графический интерфейс должен начать скрытый и позже, когда вызывается: windowStateChange («Показать») он должен показать, на windowStateChange («Скрыть») он должен скрыться. Это не так, как при запуске приложения, это видно за 0,5 с (я вижу, что он мигает). Есть ли способ заставить его начать скрываться и не мигать полсекунды.
2 что windowStateChange не работает должным образом при вызове myThreadHandler (Queue.Work).
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 ("Показать"); изнутри другой нити показывает gui, но не совсем. Как я вижу, что он хотел бы показать, но это не так. Как повесить приложение. Но когда Thread.Sleep (5000) пропускает скрытие приложения.
Призвание:
Program.mainAnnounceWindow.setLogTextBox(task);
Program.mainAnnounceWindow.setLogTrayTip(task);
не имеет никаких проблем. BaloonTip показывает, что Gui не отображается правильно. Что-то я делаю неправильно.
О, и, конечно, я сделал некоторые вырезать/вставить, чтобы он мог пропустить некоторые вещи. Если нужно добавить что-то, дайте мне знать.
С уважением,
MadBoy
myThreadGuiAnnounce.Start(); запускает поток private static void showGuiAnnounce() {mainAnnounceWindow.ShowDialog(); }, так что на самом деле GUI имеет свою собственную ветку отдельно от Main. Итак, Threa.Sleep (1000) просто заставляет Main thread спать и ничего не делать, пока gui находится в другом потоке? Разве это не работает? – MadBoy
Это не будет безопасно. Новый поток должен быть запущен STA, и если вы используете ShowDialog, окно не будет обрабатывать сообщения и быть в состоянии скрыть то, что вы хотите. Оставьте окно в главном потоке и покажите его нормально (без диалога), и ваш код, скорее всего, сработает wya, который вы хотите ... –
Действительно. Если я не использую отдельный поток для создания mainAnnounceWindow .. и я использую Main thread как поток Gui, ваше решение работает. Но что, если бы я хотел бы, чтобы Main thread остался для других вещей (поскольку Thread.Sleep был там, поэтому Main thread не выходил. – MadBoy