在可以調用 OLE 之前,必須將當前線程設定為單一執行緒 Apartment(STA)模式。請確保您的 Main 函數帶有 STAThreadAttribute 標記。 只有將調試器附加到該進程才會引發此異常。
程式之前運行正常,我只是在一個事件中定義了做了如下操作,程式拋出此異常
Code
private void OnExportPlan(object sender, EventArgs e)
{
try
{
if (null != ExportPlan)
{
Cursor = Cursors.WaitCursor;
saveFileDialog1.Filter = "(Excel2003).xls|*.xls|(Excel2007).xlsx|*.xlsx";
if (DialogResult.OK == saveFileDialog1.ShowDialog())
{
mExportFilePath = saveFileDialog1.FileName;
Application.DoEvents();
ExportPlan(this, null);
}
}
}
finally
{
Cursor = Cursors.Default;
}
}
查看MSDN,有如下說明:
單元是進程內部具有相同線程訪問要求的對象的邏輯容器。同一單元中的所有對象都可以接收從該單元中的任何線程發出的調用。.NET Framework 不使用單元,託管對象自己負責以安全執行緒的方式使用所有共用資源。
由於 COM 類別使用單元,因此公用語言運行庫需要在 COM interop 的情況下調用 COM 物件時建立並初始化一個單元。託管線程可以建立並進入只允許有一個線程的單一執行緒 Apartment (STA) 或者包含一個或多個線程的多執行緒 Apartment (MTA)。通過將線程的 ApartmentState 屬性設定為 ApartmentState 枚舉值之一,可以控制所建立的單元的類型。由於給定線程只能初始化 COM 單元一次,因此在第一次調用Unmanaged 程式碼之後就不能更改單元類型。
成員定義:
STA:Thread 將建立並進入一個單一執行緒 Apartment。
MTA:Thread 將建立並進入一個多執行緒 Apartment
Unknown:尚未設定 ApartmentState 屬性。
解決辦法兩種:
1) 在Main入口添加STAThread的Attribute
Code
[STAThread]
static void Main()
2)
Code
Thread app = new Thread(new ParameterizedThreadStart(ShowWindow));
app.ApartmentState = ApartmentState.STA;
//也可以
Thread newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.SetApartmentState(ApartmentState.MTA);
轉載請註明原創地址:http://www.cnblogs.com/winzheng/archive/2008/12/02/1345656.html
例如:
Code
static void Main()
{
Thread newThread =
new Thread(new ThreadStart(ThreadMethod));
newThread.SetApartmentState(ApartmentState.MTA);
// The following line is ignored since
// ApartmentState can only be set once.
newThread.SetApartmentState(ApartmentState.STA);
Console.WriteLine("ThreadState: {0}, ApartmentState: {1}",
newThread.ThreadState, newThread.ApartmentState);
newThread.Start();
// Wait for newThread to start and go to sleep.
Thread.Sleep(300);
try
{
// This causes an exception since newThread is sleeping.
newThread.SetApartmentState(ApartmentState.STA);
}
catch(ThreadStateException stateException)
{
Console.WriteLine("\n{0} caught:\n" +
"Thread is not in the Unstarted or Running state.",
stateException.GetType().Name);
Console.WriteLine("ThreadState: {0}, ApartmentState: {1}",
newThread.ThreadState, newThread.GetApartmentState());
}
}
static void ThreadMethod()
{
Thread.Sleep(1000);
}