Отображение формы блокирует моно - PullRequest
2 голосов
/ 15 июля 2011

У меня есть моно-приложение, написанное на c # и запущенное на Mac с помощью «mono myapp.exe»

Само приложение является «приложением 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
    }
}

Внутри метода Start UserClient есть фрагмент кода, который непрерывно отслеживает сервер, который дает ему инструкции на выполнение действий.Одна из вещей, которую он делает, - при желании отображает сообщение в форме окна.

Когда сервер инструктирует процесс для отображения сообщения, он создает экземпляр формы, отображает ее с помощью frm.ShowDialog(), а затем через 30 секунд запускается метод Close () с таймером, после чего frm удаляется.Однако, когда это происходит, на моем Mac я вижу строку заголовка приложения с надписью «моно» и новый значок на панели инструментов для монофонического приложения.Примерно через 2 минуты моно процесс в Activity Monitor показывает «Не отвечает».Это в конечном итоге предотвратит выход пользователя из системы, завершение работы и т. Д. (Потому что Mac OS не может убить моно изящно).

НА ДРУГОЙ РУКЕ ... если сервер никогда не сообщит процессу об этомформа, все работает нормально и шикарно: значок дока никогда не появляется (что хорошо!), строка заголовка моно никогда не появляется, и процесс моно продолжает работать счастливо, не мешая системе выключаться или перезагружаться.

Кто-нибудь испытал это или есть идеи о том, что его вызывает?Я предполагаю, что это новый поток GUI, созданный формой, который никогда не закрывается и каким-то образом вызывает блокировку, хотя я не уверен, как с этим справиться.

Спасибо за любые предложения.

Обновление:

Вот код, который легко воспроизвести и увидеть, как это происходит.Я понимаю, что это кажется «нестандартным».Сказав это, нижеприведенное прекрасно работает в среде Windows и обеспечивает желаемый результат, когда значок не отображается в области задач, кроме случаев, когда отображается сообщение.В настоящее время использование Application.Run и простое выполнение frm.ShowDialog () дают точно такой же результат.

В конце концов нам нужно отобразить форму, а затем уничтожить форму и все связанные значки с док-станции.Я подозреваю, что графический интерфейс запускает поток, который никогда не удаляется, поэтому значок дока остается.Есть ли способ убедиться, что с потоком 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 ]

1 голос
/ 16 июля 2011

Я не вижу ничего похожего на инициализацию цикла сообщений для оконного приложения. То есть в окнах формы бывает что-то вроде Application.Run(). Если у вас его нет, неудивительно, что приложение зависает. В любом случае, может быть полезно разместить больше кода, как указано в комментарии.

1 голос
/ 15 июля 2011

Я чувствую, что мне не хватает нескольких вещей. Наиболее заметно

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

См. Также этот ответ: Проблема Windows Forms и ShowDialog

0 голосов
/ 11 августа 2011

В конце концов, я не смог решить это. Я создал процесс, который запустил другое приложение, которое отображало форму сообщения. Не совсем верный ответ, но решение, с которым мне пришлось столкнуться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...