Note that there are some explanatory texts on larger screens.

plurals
  1. POApplication.Run(form) never returns (after using System::Management)
    primarykey
    data
    text
    <p>I have a class library assembly that once loaded opens one form (form1) and when prompted form1 opens other forms(form2). Each form runs in a separate thread , this is because in each form runs a flashweave applicatin and for performance i need to run them in separate theads. If i load the library using a managed loader written in c# everything works ok. If i load the library using a mixed clr/c++ assembly , when a form2 gets closed Application.Run() dooesn't return resulting in many stuck threads. I tried also to force abort the threads using Thread.Abort() but still the thread doesn't abort. If i close form1 application.run() returns and it's thread can stop. I also tried to open simple empty forms instead of form2 without any flashwave object in them , and still it doesn't return.</p> <p>Maybe the problem is connected with this message that i get sometime:</p> <blockquote> <p>The CLR has been unable to transition from COM context 0x197060 to COM context 0x196ef0 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.</p> </blockquote> <p>About form2 opening: </p> <pre><code>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) { } } </code></pre> <p>Stack trace for a stuck thread:</p> <blockquote> <p>ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 byte ntdll.dll!_ZwWaitForMultipleObjects@20() + 0x15 byte KernelBase.dll!_WaitForMultipleObjectsEx@20() + 0x36 byte kernel32.dll!_WaitForMultipleObjectsExImplementation@20() + 0x8e byte user32.dll!_RealMsgWaitForMultipleObjectsEx@20() + 0xe2 byte ole32.dll!CCliModalLoop::BlockFn() + 0x96 byte<br> ole32.dll!_CoWaitForMultipleHandles@20() - 0x51b9 byte mscorwks.dll!NT5WaitRoutine() + 0x39 byte mscorwks.dll!MsgWaitHelper() + 0x97 byte mscorwks.dll!Thread::DoAppropriateAptStateWait() - 0xf32e5 byte mscorwks.dll!Thread::DoAppropriateWaitWorker() + 0x104 byte mscorwks.dll!Thread::DoAppropriateWait() + 0x40 byte mscorwks.dll!CLREvent::WaitEx() + 0x1438a9 byte<br> mscorwks.dll!CLREvent::Wait() + 0x17 byte<br> mscorwks.dll!WKS::GCHeap::FinalizerThreadWait() + 0xec byte mscorwks.dll!ReleaseRCWsInCaches() + 0xe34fd byte<br> mscorwks.dll!ReleaseRCWsInCachesNoThrow() + 0x67 byte mscorwks.dll!Thread::CleanupCOMState() + 0x1b8f83 byte mscorwks.dll!Thread::OnThreadTerminate() + 0x46 byte mscorwks.dll!DestroyThread() + 0x3b byte<br> mscorwks.dll!ThreadNative::KickOffThread() + 0xf2 byte mscorwks.dll!Thread::intermediateThreadProc() + 0x46 byte kernel32.dll!@BaseThreadInitThunk@12() + 0x12 byte</p> </blockquote> <p>Regarding the code that shows the first thread is:</p> <pre><code>//c++ code Assembly::form^ f= gcnew Assembly::form() ; f-&gt;Load(); gcroot&lt;Assembly::form^&gt;* dsa3_gc_p= new gcroot&lt;Assembly::form^&gt;(f); this-&gt;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(); } </code></pre> <p>NEWS: Finally i've found what generate this behaviour. Before instantiating the c# library, the loader try to get the cpu serial by using .net System::Management, if i remove such part then all works ok. This is the guilty part:</p> <pre><code>std::string Loader::GetCPUID() { std::string lsCPUID = ""; try { System::Management::ManagementObjectCollection^ moReturn = nullptr; System::Management::ManagementObjectSearcher^ moSearch ; moSearch = gcnew System::Management::ManagementObjectSearcher("Select * from Win32_Processor"); moReturn = moSearch-&gt;Get(); for each ( System::Management::ManagementObject^ mo in moReturn ) { char * chp = (char *) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(mo["ProcessorID"]-&gt;ToString()).ToPointer(); lsCPUID.assign(chp); } } catch(System::Exception^ ex ) { } return lsCPUID; } </code></pre> <p>Thanks.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload