C# .NET을 통해 다른 응용 프로그램 용 플러그인을 작성하고 있습니다. 내 플러그인이 수행해야하는 프로세스 중 오히려 시간이 많이 걸리기 때문에 여러 스레드를 활용하고 싶기 때문에 사용자가 진행중인 모든 작업 대신 현재 진행중인 작업의 진행률 표시 줄을 보여줄 수 있습니다.두 번째 스레드에서 양식을 만드는 데 문제가 있습니다.
일반적으로 이와 같은 항목의 UI는 주 스레드에서 만들어지고 보조 스레드는 BackGroundWorker 클래스 등을 통해 작업을 수행하기 위해 만들어집니다. 그러나 제 경우에는 이 메인 스레드에서 수행되어야합니다. 플러그인을 작성하고있는 응용 프로그램은 플러그인에 액세스하기 위해 작성한 스레드 이외의 다른 스레드에 만족하지 않기 때문입니다.
그래서 대신 (WinForms 양식)에서 내 UI를 만드는 두 번째 스레드를 만들고, 실제 작업을 수행하기 위해 주 스레드로 다시 통신합니다.
주 스레드에서 내 양식을 만들 수 있지만 두 번째 스레드에서 양식을 인스턴스화하려고하면 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:
업데이트 나는이 STA에 보조 UI 스레드의 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
@VinayC 코드 –