【问题标题】:ThreadState exception in initialization初始化中的 ThreadState 异常
【发布时间】:2011-04-18 21:23:09
【问题描述】:

问了好久,先总结一下,

  • 我的 Messenger 项目有一个 Client 类。
  • 我的 Client 类有一个 Socket。
  • 我使用它的 BeginReceive 方法从服务器获取消息。
  • 在 BeginReceive 的异步回调中,我使用 EndReceive 获取消息。
  • 当我收到消息时,我会触发带有消息本身的 MessageReceived 事件。
  • 我在消息表单中使用了这个客户端类。
  • 在消息形式中,我可以通过将方法附加到 Client.MessageReceived 来获取接收到的消息。
  • 为此我使用 OnMessageReceived 方法。
  • 收到消息后,我可以在 TextBox(使用 Control.Invoke)或 MessageBox 上显示它。
  • 我还可以在 OnMessageReceived 中的 TabControl 中添加一个新选项卡。
  • 当我尝试初始化 WebBrowser 控件时,我得到了 ThreadStateException。
  • 我用来显示消息的控件来自 WebBrowser 控件,所以我需要它。
  • Threading.Thread.CurrentThread.ThreadState 为“背景”。

我认为您不需要详细信息,但您可以在下面找到我最初打算发布的详细问题。

非常感谢。


我正在使用 Net.Socket 的异步方法处理一个信使项目(服务器是 Windows 服务,客户端是 Windows 窗体应用程序)。 我在 Socket.BeginReceive 的回调中触发客户端的 MessageReceived 事件; 直到这里,一切都是我希望他们成为的样子。

我在我的表单中使用 MessageReceived 事件(两个人互相写信的事件)我可以使用 Control.Invoke 方法(如果需要)对 UI 做任何我想做的事情,但有一个烦人的异常。

我在表单中有选项卡式对话,因此当消息到达时,我会检查是否与发件人有打开的对话(选项卡)。如果是,我选择该选项卡并显示消息。如果不是,我创建一个新的 ConversationTab。

现在,如果这个问题太长,或者我无法充分解释自己,我很抱歉。英语不是我的第一语言,这是我在 Stack Overflow 上的第一个问题。 所以,这里是对话标签:

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。跑题了?对不起。

这是我在 MessageReceived 事件触发时调用的 NewConversation 方法:

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”获取或设置 TabControl 的 SelectedTab 属性。 我创建这些属性的重点主要是内部的线程安全逻辑。

所以问题是:它在上述代码的“tab = new ConversationTab(friend)”部分抛出了 ThreadStateException。它是第一个代码的“MessageBrowser = new MessageBrowser()”部分,也是MessageBrowser的构造函数。我之所以没有提供 MessageBrowser 的构造函数代码是因为在执行任何内部代码行之前引发了异常(这是关于 WebBrowser 的构造函数,当我尝试初始化 WebBrowser 时也会出现此异常。) 实际上我什至没有得到异常,应用程序只是在那里关闭而没有通知我任何事情。当我尝试在 Watch 窗口中的 ConversationTab 的构造函数上调用“MessageBrowser = new MessageBrowser()”时看到了异常。

我对使用线程和异步方法有点陌生。 MSDN 说:

ThreadStateException 由由于线程当前状态而无法执行请求操作的方法引发。

在我的例子中,线程的状态是“Background”。 我不知道我做错了什么。

非常感谢您阅读全文,如果您能提供帮助,我们将更加感谢您。

【问题讨论】:

  • 你使用Control.Invoke()调用那个NewConversation方法吗?
  • 其实没有,我没用过。我认为 InvokeRequired 足以决定我是否需要使用 Invoke。好吧,后台线程是 MTA,并且不会阻止 InvokeRequired 返回 true(为什么应该这样做?)所以我使用了我的 Form(在 STA 线程上运行)的 Invoke 方法来封装进程。谢谢。

标签: c# multithreading sockets asynchronous


【解决方案1】:

这似乎与在 .NET 中使用 COM(Web 浏览器控件使用 COM)有关,其中线程单元需要设置为 STA

尝试将[STAThread] 添加到您的入口点。

看看this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 2012-09-07
    • 2012-07-27
    相关资源
    最近更新 更多