【问题标题】:Current thread must be set to single thread apartment in VB.NET当前线程必须在 VB.NET 中设置为单线程单元
【发布时间】:2016-09-09 10:51:03
【问题描述】:

这是我表单中的new 方法:

Public Sub New(ByVal ConnectionString As String, ByVal ConSql As SqlClient.SqlConnection, ByVal Daman As Array, ByVal SDate As Integer, ByVal FDate As Integer)

    Threading.Thread.CurrentThread.TrySetApartmentState(Threading.ApartmentState.STA)
    ' This call is required by the Windows Form Designer.
    'Error Appear in this line
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Me.Sto_TypeFormFrameTableAdapter.Connection.ConnectionString = ConnectionString
    Me.Sto_typeformTableAdapter.Connection.ConnectionString = ConnectionString
    con = ConSql
    com.Connection = con
    ConNew = ConnectionString
    DamaneCod = Daman
    Start = SDate
    Final = FDate
    Fill()
End Sub

当我创建表单的新对象时,InitializeComponent 命令出错。

错误信息是:

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

此表单在一个项目中,其输出是另一个项目的 DLL 文件,并且在使用此 DLL 文件的另一个项目中不会出现错误。 我该如何解决?

【问题讨论】:

  • 不要在 New 过程中做那些事情。

标签: .net vb.net


【解决方案1】:

我使用了来自this site 的以下代码,它可以工作:

    using System.Threading;

    protected void Button1_Click(object sender, EventArgs e)
    {

       Thread newThread = new Thread(new ThreadStart(ThreadMethod));
       newThread.SetApartmentState(ApartmentState.STA);
       newThread.Start();     

    }

    static void ThreadMethod()
    {
       Write your code here;
    }

【讨论】:

  • 这很有帮助,但在 VB 中没有。
【解决方案2】:

不要忽略 TrySetApartmentState() 的返回值。如果您得到 False 则没有理由尝试继续,您的代码将无法正常工作。你不妨抛出一个异常。

If Not Threading.Thread.CurrentThread.TrySetApartmentState(Threading.ApartmentState.STA) Then
    Throw New InvalidOperationException("This form is only usable from the UI thread")
End If

当您尝试从控制台模式应用程序或不是 Winforms 或 WPF 应用程序的主线程的线程中使用您的代码时,您将收到此异常。对于用户界面组件来说,这些环境并不友好。

需要一个线程在它启动之前进入 STA 单元,通过应用程序的 Main 方法上的 [STAThread] 属性或通过在启动线程之前调用 Thread.SetApartmentState() .并且必须调用 Application.Run() 或 Form.ShowDialog() 以获取保持表单功能所需的消息循环。通过查看调用堆栈来调试它,看看你的构造函数是如何被调用的。使用 Debug + Windows + Threads 有助于查看这是否发生在工作线程而不是应用程序的主线程上。

【讨论】:

  • 你说我必须在 Application.Run() 或 Form.ShowDialog 之前使用 STAThread?但是我们的项目没有 Application.Run() 并且当我从 Form 创建新对象时出现错误。(在调用 Form.Show 之前)
  • 嗯,这将是您得到此异常的一个明显原因。如果您在堆栈跟踪中没有看到 Application.Run(),请使用调试器的 Threads 窗口,就像我记录的那样。
  • 在线程窗口我有6行,其中4行是工作线程,其中一个是空白的,另一个是主线程,并且错误在主线程中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
相关资源
最近更新 更多