Исключение ThreadState при инициализации - PullRequest
1 голос
/ 12 апреля 2011

Это был длинный вопрос, поэтому вот краткое изложение,

  • У меня есть класс Client для моего проекта мессенджера.
  • В классе «Мой клиент» есть сокет.
  • Я использую его метод BeginReceive для получения сообщений с сервера.
  • В асинхронном обратном вызове BeginReceive я получаю сообщение, используя EndReceive.
  • Когда я получаю сообщение, я запускаю событие MessageReceived с самим сообщением.
  • Я использую этот класс Client в форме сообщения.
  • В форме сообщения я могу получить полученное сообщение, прикрепив метод к Client.MessageReceived.
  • Я использую метод OnMessageReceived для этой цели.
  • Когда я получаю сообщение, я могу показать его в TextBox (используя Control.Invoke) или MessageBox.
  • Я также могу добавить новую вкладку в свой TabControl в OnMessageReceived.
  • Когда я пытаюсь инициализировать элемент управления WebBrowser, я получаю исключение ThreadStateException.
  • Элемент управления, который я использую для отображения сообщений, происходит от элемента управления WebBrowser, поэтому он мне нужен.
  • Threading.Thread.CurrentThread.ThreadState - это "Фон".

Не думаю, что вам понадобятся подробности, но вы можете найти подробный вопрос, который я впервые намеревался опубликовать ниже.

Большое спасибо.


Я работаю над проектом мессенджера (сервер - это служба Windows, а клиент - приложение Windows Forms) с использованием асинхронных методов Net.Socket. Я запускаю событие MessageReceived Клиента в обратном вызове Socket.BeginReceive; Все так, как я хочу, чтобы они были здесь.

Я использую событие MessageReceived в своей форме (то, которое два человека пишут друг другу). Я могу сделать все, что захочу, для пользовательского интерфейса, используя метод Control.Invoke (если требуется), с одним досадным исключением.

В форме разговоров есть вкладки, поэтому, когда приходит сообщение, я проверяю, есть ли открытая беседа (вкладка) с отправителем. Если да, я выбираю эту вкладку и отображаю сообщение. Если нет, я создаю новую вкладку ConversationTab.

Теперь, извините, если это длинный вопрос, чем он должен быть, или если я не могу объяснить себя достаточно. Английский не мой родной язык, и это мой первый вопрос в переполнении стека. Итак, вот таблица разговоров:

public class ConversationTab : TabPage
    {
        public User Friend { get; private set; }
        public MessageBrowser MessageBrowser { get; private set; }

        public ConversationTab(User friend) : base(friend.DisplayName)
        {
            Friend = friend;
            MessageBrowser = new MessageBrowser();
            Controls.Add(MessageBrowser);
            MessageBrowser.Dock = DockStyle.Fill;   
        }
    }

MessageBrowser является производным от WebBrowser, и причина, по которой я его использую, заключается в том, что я не мог применять собственные стили (цвет, шрифт, размер) «к сообщению» с помощью RichTextBox. RichTextBox.SelectedColor не всегда работает, или я не мог заставить его работать как задумано. MessageBrowser позволяет мне использовать CSS вместо этого. Блуждающий от предмета? К сожалению.

Вот метод NewConversation, который я вызываю при возникновении события MessageReceived:

public void NewConversation(User friend)
    {
        ConversationTab tab = Conversations.FirstOrDefault(c => c.Friend.Id == friend.Id);

        if (tab != null)
            ActiveConversation = tab;
        else
        {
            tab = new ConversationTab(friend);
            // add tab to TabControl
        }

        // bla
    }

«Conversations» получает вкладки TabControl, а «ActiveConversation» получает или устанавливает свойство SelectedTab TabControl. Моя точка зрения при создании этих свойств заключается в основном в логике безопасности потоков.

Таким образом, вопрос: он вызывает исключение ThreadStateException в "tab = new ConversationTab (friend)" части вышеприведенного кода. Это часть MessageBrowser = new MessageBrowser () первого кода и конструктор MessageBrowser. Причина, по которой я не предоставил код конструктора MessageBrowser, заключается в том, что исключение выдается до выполнения какой-либо строки внутреннего кода (это касается конструктора WebBrowser, я получаю это исключение и при попытке инициализировать WebBrowser). На самом деле я даже не получаю исключения, приложение просто закрывается там, не уведомляя меня ни о чем. Я увидел исключение при попытке вызвать MessageBrowser = new MessageBrowser () для конструктора ConversationTab в окне Watch.

Я новичок в использовании потоков и асинхронных методов. MSDN говорит:

ThreadStateException вызывается методами, которые не могут выполнить запрошенную операцию из-за текущего состояния потока.

В моем случае состояние потока - "Фон". Я понятия не имею, что я делаю неправильно.

Большое спасибо, если вы прочитали все это, и большое спасибо, если вы можете помочь.

1 Ответ

1 голос
/ 12 апреля 2011

Это, по-видимому, связано с использованием COM (управление веб-браузером использует COM) в .NET, где необходимо установить квартиру потока STA.

Попробуйте добавить [STAThread] к вашей точке входа.

Посмотрите на это .

...