Это был длинный вопрос, поэтому вот краткое изложение,
- У меня есть класс 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 вызывается методами, которые не могут выполнить запрошенную операцию из-за текущего состояния потока.
В моем случае состояние потока - "Фон".
Я понятия не имею, что я делаю неправильно.
Большое спасибо, если вы прочитали все это, и большое спасибо, если вы можете помочь.