我正在通過C#.NET爲另一個應用程序編寫插件。我的插件必須執行的某些流程相當耗時,所以我想利用多個線程,以便向用戶顯示進度條,說明當前任務的進度情況,而不是整個事件的懸掛情況。無法在第二個線程上創建表單
通常在主線程中會創建類似於此的UI,並且會創建輔助線程來完成工作,例如通過BackGroundWorker類。但是,在我的情況下,工作必須在主線程中完成,因爲我正在編寫插件的應用程序對於其他線程不滿意,因爲它爲創建的插件創建的線程無法訪問它。
因此,我正在創建第二個線程來創建我的UI(WinForms表單),然後與主線程進行通信以完成任何實際工作。
我可以在主線程中創建我的表單,但是當我嘗試在第二個線程中實例化表單時,我得到一個InvalidOperationException異常。這發生在設計器文件中,用於設置列表視圖中列名稱屬性的窗體。
以下是例外的詳細信息。
System.InvalidOperationException was caught
Message=ColumnInfo cannot be set.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.ListView.SetColumnInfo(Int32 mask, ColumnHeader ch)
at System.Windows.Forms.ColumnHeader.set_Text(String value)
at QA.Revit.RevitQAForm.InitializeComponent() in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\QA Tool\RevitModelCheckerPlugIn\RevitQAForm.Designer.cs:line 758
at QA.Revit.RevitQAForm..ctor() in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\QA Tool\RevitModelCheckerPlugIn\RevitQAForm.cs:line 34
at QA.Revit.RevitQAToolApp.FormMethod() in C:\Documents and Settings\eric.anastas\My Documents\_SVN WC\QA Tool\RevitModelCheckerPlugIn\RevitModelCheckerCmd.cs:line 99
InnerException:
更新
我似乎已經得到了這個,現在通過改變二次UI線程STA的工作的ApartmentState。儘管我對這個多線程的東西一無所知,但不知道ApartmentState或STA的含義。
這裏是我的代碼。
//property used to store a reference to the form
internal RevitQAForm RevitQAForm { get; set; }
//monitor object that when pulsed shows the form
public static readonly Object showFormLock = new object();
//this method is called by the parent app when it starts
public Autodesk.Revit.UI.Result OnStartup(Autodesk.Revit.UI.UIControlledApplication application)
{
//this creates the form UI Thread
_formThread = new System.Threading.Thread(new System.Threading.ThreadStart(FormMethod));
_formThread.Name = "Form Thread";
_formThread.SetApartmentState(System.Threading.ApartmentState.STA);
_formThread.Start();
//returns that the plug-in startup succeeded
return Autodesk.Revit.UI.Result.Succeeded;
}
//the method is started on the second thread
private void FormMethod()
{
try
{
//creates the form
RevitQAForm = new RevitQAForm();
lock (showFormLock)
{
while (true)
{
//waits for a pulse
System.Threading.Monitor.Wait(showFormLock);
RevitQAForm.ShowDialog();
}
}
}
catch (System.Threading.ThreadAbortException)
{
//disposes the form if the thread is aborted
RevitQAForm.Dispose();
}
}
//this is called when the user request the form be shown
public void ShowForm()
{
lock (showFormLock)
{
System.Threading.Monitor.Pulse(showFormLock);
}
}
//this is called when the program closes
public Autodesk.Revit.UI.Result OnShutdown(Autodesk.Revit.UI.UIControlledApplication application)
{
//aborts the form thread
formThread.Abort();
return Autodesk.Revit.UI.Result.Succeeded;
}
就像我說的這似乎現在工作。我可以用我的插件啓動應用程序並重復顯示錶單。當我關閉程序時,表格也會被處理。
然而,現在我想弄清楚這個表單可以如何傳遞迴主線程。表單將需要能夠觸發主線程開始處理,然後主線程需要能夠定期向進程返回表單線程。在任何時候,表單線程應該能夠告訴主線程取消處理。最後,當處理完成時,主線程需要通知表單。
任何人都有關於如何做到這一點的提示?
爲了完整起見,您可以分享創建表單並啓動它的代碼嗎? – VinayC 2011-01-21 04:07:11
@VinayC我更新了我的帖子,代碼爲 – 2011-01-21 05:00:29