C# Application.Run(form)永远不会返回(在使用System::Management之后)
我有一个类库程序集,一旦加载就会打开一个表单(form1),当提示时,form1会打开其他表单(form2)。每个窗体在单独的线程中运行,这是因为在每个窗体中运行一个flashweave应用程序,为了提高性能,我需要在单独的线程中运行它们。 如果我使用c语言编写的托管加载程序加载库,一切正常。 如果我使用混合clr/c++程序集加载库,当form2关闭时,Application.Run()将不会返回,从而导致许多线程卡住。 我还尝试使用Thread.abort()强制中止线程,但线程仍然没有中止。 如果我关闭form1应用程序,run()返回,它的线程可以停止。 我还尝试打开简单的空表单,而不是没有任何flashwave对象的form2,但仍然没有返回C# Application.Run(form)永远不会返回(在使用System::Management之后),c#,.net,c++,visual-c++,C#,.net,C++,Visual C++,我有一个类库程序集,一旦加载就会打开一个表单(form1),当提示时,form1会打开其他表单(form2)。每个窗体在单独的线程中运行,这是因为在每个窗体中运行一个flashweave应用程序,为了提高性能,我需要在单独的线程中运行它们。 如果我使用c语言编写的托管加载程序加载库,一切正常。 如果我使用混合clr/c++程序集加载库,当form2关闭时,Application.Run()将不会返回,从而导致许多线程卡住。 我还尝试使用Thread.abort()强制中止线程,但线程仍然没有中止
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
也许问题与我收到的消息有关:
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
CLR无法转换
从COM上下文0x197060到COM
上下文0x196ef0持续60秒。这个
拥有目标的线程
上下文/公寓是最有可能的
进行非泵送等待或
处理一个非常长的运行时间
无泵送窗操作
信息。这种情况普遍存在
对绩效产生负面影响,并可能
甚至导致应用程序变得
无响应或内存使用
随着时间的推移不断积累。到
避免这个问题,所有的单
螺纹单元(STA)螺纹
应该使用泵送等待原语
(如CoWaitForMultipleHandles)和
在长时间内定期发送消息
运行操作
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
关于form2开幕式:
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
卡住线程的堆栈跟踪:
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
ntdll.dll_ZwWaitForMultipleObjects@20()
+0x15字节的ntdll.dll_ZwWaitForMultipleObjects@20()
+0x15字节的KernelBase.dll_WaitForMultipleObjectsEx@20()
+0x36字节内核32.dll_WaitForMultipleObjectsExImplementation@20()
+0x8e字节user32.dll_RealMsgWaitForMultipleObjectsEx@20()
+0xe2字节ole32.dll!CCliModalLoop::BlockFn()+
0x96字节ole32.dll_CoWaitForMultipleHandles@20() -0x51b9字节mscorwks.dll!NT5WaitRoutine()+0x39 字节mscorwks.dll!MsgWaitHelper() +0x97字节mscorwks.dll!线程::DoAppropriateAptStateWait() -0xf32e5字节mscorwks.dll!线程::DoAppropriateWaitWorker() +0x104字节mscorwks.dll!线程::DoAppropriateWait() +0x40字节的mscorwks.dll!CLREvent::WaitEx()+ 0x1438a9字节
mscorwks.dll!CLREvent::Wait()+0x17 字节
mscorwks.dll!WKS::GCHeap::FinalizerThreadWait() +0xec字节mscorwks.dll!ReleaseRCWsInCaches()+ 0xe34fd字节
mscorwks.dll!ReleaseRCWsInCachesNoThrow() +0x67字节的mscorwks.dll!线程::CleanupCOMState() +0x1b8f83字节mscorwks.dll!线程::OnThreadTerminate() +0x46字节mscorwks.dll!销毁线程()+0x3b 字节
mscorwks.dll!ThreadNative::KickOffThread() +0xf2字节mscorwks.dll!线程::intermediateThreadProc() +0x46字节内核32.dll@BaseThreadInitThunk@12() +0x12字节
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
关于显示第一个线程的代码:
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
//c++ code
Assembly::form^ f= gcnew Assembly::form() ;
f->Load();
gcroot<Assembly::form^>* dsa3_gc_p= new gcroot<Assembly::form^>(f);
this->obMainLib = (void *)dsa3_gc_p;
//------------------------
//The c++ loader just calls the Load() method
//c#library
public void Load()
{
FormThread = new Thread(new ThreadStart(this.Start));
FormThread.Name = "T7";
FormThread.IsBackground = true;
FormThread.SetApartmentState(ApartmentState.STA);
FormThread.Start();
}
private void Start()
{
Config = GlobalConfig.GetConfig(GlobalConfig.ConfigurationFile);
HttpInterface = new DHttpInterface(Config);
Lobby = new FormLobby(HttpInterface, false);
WorkerThread = new Thread(new ThreadStart(this.Start));
WorkerThread.Name = "T6";
WorkerThread.IsBackground = true;
WorkerThread.ApartmentState = ApartmentState.STA;
WorkerThread.Start();
Application.Run(Lobby);
Config.SaveToDisk();
}
谢谢。您是否可能是从MTA线程调用OpenTable,而InvokeRequest返回true,因此它不会创建另一个STA线程,而是直接调用MTA线程上的Application.Run()
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
尝试从STA线程调用Application.Run()。我终于找到了方法。我创建了一个新的AppDomain,其中我运行了获取cpu序列号的方法,然后卸载了该域,从而卸载了导致问题的System::Management库
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
引用类MarshalByRefType:MarshalByRefObject
{
公众:
//通过代理调用此方法
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
std::string GetCPUID()
{
//char * chp = (char *) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(R671::R671::Value()).ToPointer();
std::string lsCPUID = "";
//return lsCPUID.assign(chp);
try
{
System::Management::ManagementObjectCollection^ moReturn = nullptr;
System::Management::ManagementObjectSearcher^ moSearch ;
moSearch = gcnew System::Management::ManagementObjectSearcher("Select * from Win32_Processor");
moReturn = moSearch->Get();
for each ( System::Management::ManagementObject^ mo in moReturn )
{
char * chp = (char *) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(mo["ProcessorID"]->ToString()).ToPointer();
lsCPUID.assign(chp);
}
}
catch(System::Exception^ ex )
{
}
AppDomainSetup^ ads = AppDomain::CurrentDomain->SetupInformation;
String^ str = String::Format("AppName={0}, AppBase={1}, ConfigFile={2}",
ads->ApplicationName,
ads->ApplicationBase,
ads->ConfigurationFile);
char * chp = (char *) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer();
lsCPUID.assign(chp);
return lsCPUID;
}
}
private void OpenTable()
{
if (!this.InvokeRequired)
{
Thread TableRun = new Thread(new ThreadStart(OpenTable));
TableRun.ApartmentState = ApartmentState.STA;
TableRun.IsBackground = false;
TableRun.Name = "T2";
TableRun.Start();
return;
}
try
{
FormTable T = new FormTable(;
T.MyThread = Thread.CurrentThread;
Application.Run(T);
}
catch (Exception ex)
{
}
}
MyThread如何不抛出NullReferenceException?为什么要抛出?但是你可以跳过它。。。我只是后来添加了它,以提供对线程的引用,并试图粗暴地中止它,但它不起作用。哎呀,我修剪了一些不有用的部分,还修剪了FormTable被实例化的部分。。。我将编辑它。如果添加C++代码来加载程序集并显示第一个窗体,这将是有益的。使用调试器的线程窗口来了解它正在做什么。启用Microsoft symbol服务器以获得良好的堆栈跟踪。否,所有线程都是STA线程。而且该线程不能是MTA线程,因为它是form1的线程。