【问题标题】:Single thread apartment issue单线程公寓问题
【发布时间】:2012-11-27 08:56:31
【问题描述】:

在我的主窗体中,我调用以下命令来打开一个新窗体

MyForm sth = new MyForm();
sth.show();

一切都很好,但是这个表单有一个组合框,当我将它的 AutoCompleteMode 切换为建议和附加时,我在显示表单时遇到了这个异常:

在进行 OLE 调用之前,必须将当前线程设置为单线程单元 (STA) 模式。确保您的 Main 函数上标记了 STAThreadAttribute。

我已经按照异常的要求在我的主函数上设置了这个属性:

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

我能否得到一些帮助以了解可能出现的问题。

示例代码:

private void mainFormButtonCLick (object sender, EventArgs e)
{
    // System.Threading.Thread.CurrentThread.SetApartmentState(ApartmentState.STA); ?
    MyForm form = new MyForm();
    form.show();
}

设计师:

this.myCombo.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
this.myCombo.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.myCombo.FormattingEnabled = true;
this.myCombo.Location = new System.Drawing.Point(20, 12);
this.myCombo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.myCombo.Name = "myCombo";
this.myCombo.Size = new System.Drawing.Size(430, 28);
this.myCombo.Sorted = true;
this.myCombo.TabIndex = 0; phrase";

设置数据源

public MyForm(List<string> elem)
{
    InitializeComponent();
    populateColorsComboBox();
    PopulateComboBox(elem);
}

public void PopulateComboBox(List<string> list )
{
    this.myCombo.DataSource = null;
    this.myCombo.DisplayMember = "text";
    this.myCombo.DataSource = list;
}

【问题讨论】:

  • 如果清理并重建项目会怎样?
  • 你见过类似的question吗?
  • 您如何显示表单?在主线程内还是在单独的线程内?
  • 我没有使用任何 BackgroundWOrker,只是在与 MainForm 相同的线程上创建所有内容
  • 如果您在致电form.Show() 之前添加if (Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA) MessageBox.Show("Not STA");,是否会显示消息框?

标签: c# winforms multithreading thread-safety


【解决方案1】:

Main(string[] args) 真的是你的切入点吗?

也许你有另一个没有参数的 Main() 重载。或另一个类中的其他一些 Main() 。请打开项目属性并查找起始对象。

【讨论】:

    【解决方案2】:

    Windows 窗体应用程序必须以 STA 方法运行。

    请看这里:Could you explain STA and MTA?

    COM 开始发挥作用,因为 Windows 窗体开始发挥作用,因为控件本身使用本机 Windows 句柄,因此必须遵守 STA 模型。我确实相信您在这个特定位置收到错误的原因是 AutoCompletion 在内部创建/使用了第二个线程。

    据我的经验,线程模型必须在 Main 中设置,以后更改它只能从 STA 到 MTA,但不能反过来

    【讨论】:

      【解决方案3】:

      作为一个疯狂的想法:以第二种形式创建源列表的深层副本,并将组合框绑定到列表的副本而不是原始列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-19
        相关资源
        最近更新 更多