public static object CreateInMTA(Type type) { if (IsNoContextMTA()) { return Activator.CreateInstance(type); } MTARequest request = new MTARequest(type); lock (critSec) { if (!workerThreadInitialized) { InitWorkerThread(); workerThreadInitialized = true; } int index = reqList.Add(request); if (!evtGo.Set()) { reqList.RemoveAt(index); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } request.evtDone.WaitOne(); if (request.exception != null) { throw request.exception; } return request.createdObject; }
public static object CreateInMTA(Type type) { if (IsNoContextMTA()) { return(Activator.CreateInstance(type)); } MTARequest request = new MTARequest(type); lock (critSec) { if (!workerThreadInitialized) { InitWorkerThread(); workerThreadInitialized = true; } int index = reqList.Add(request); if (!evtGo.Set()) { reqList.RemoveAt(index); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } request.evtDone.WaitOne(); if (request.exception != null) { throw request.exception; } return(request.createdObject); }
/* * [DllImport("kernel32")] static extern IntPtr CreateEvent(IntPtr pSecurity, int manual, int initial, IntPtr name); * [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int SetEvent(IntPtr handle); * [SuppressUnmanagedCodeSecurity, DllImport("kernel32")] static extern int WaitForSingleObject(IntPtr handle, int timeout); * IntPtr hDoIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero); * IntPtr hDoneIndicate = CreateEvent(IntPtr.Zero, 0, 0, IntPtr.Zero); */ // Worker thread for each EventSource // // Ensure we are able to trap exceptions from worker thread. // Called from IndicateEvents which in turn is protected from // concurrent access. // public void MTAWorkerThread2() { while (true) { doIndicate.WaitOne(); //WaitForSingleObject(hDoIndicate, -1); if (alive == false) { break; } // get requests from the request queue. Since two Set within short time on evtGo can wake this thread only once // workerthread should check until we empty all the results. Even if we consume the request that is not set, // workerthread will wake up one more time unnecessarily and do nothing while (true) { MTARequest reqToProcess = null; lock (critSec) { if (reqList.Count > 0) { reqToProcess = (MTARequest)reqList[0]; reqList.RemoveAt(0); } else { break; // break the inner while true } } try { if (pSinkMTA != null) { int hresult = pSinkMTA.Indicate_(reqToProcess.lengthFromSTA, reqToProcess.objectsFromSTA); if (hresult < 0) { if ((hresult & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult); } else { Marshal.ThrowExceptionForHR(hresult); } } } } catch (Exception e) { reqToProcess.exception = e; } finally { reqToProcess.doneIndicate.Set(); //SetEvent(hDoneIndicate); GC.KeepAlive(this); } } } }
public void IndicateEvents(int length, IntPtr[] objects) { if (pSinkMTA == null) { return; } // // Checking for MTA is not enough. We need to make sure we are not in a COM+ Context // if (MTAHelper.IsNoContextMTA()) { // Sink lives in MTA int hresult = pSinkMTA.Indicate_(length, objects); if (hresult < 0) { if ((hresult & 0xfffff000) == 0x80041000) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult); } else { Marshal.ThrowExceptionForHR(hresult); } } } else { MTARequest myReq = new MTARequest(length, objects); int ndx; lock (critSec) { // Do it from worker thread if (workerThreadInitialized == false) { // We've never created worker thread Thread thread = new Thread(new ThreadStart(MTAWorkerThread2)); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.MTA); thread.Start(); workerThreadInitialized = true; } ndx = reqList.Add(myReq); if (doIndicate.Set() == false) //SetEvent(hDoIndicate); { reqList.RemoveAt(ndx); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } myReq.doneIndicate.WaitOne(); //WaitForSingleObject(hDoneIndicate, -1); if (myReq.exception != null) { throw myReq.exception; } } GC.KeepAlive(this); }
public void IndicateEvents(int length, IntPtr[] objects) { if (this.pSinkMTA != null) { if (MTAHelper.IsNoContextMTA()) { int errorCode = this.pSinkMTA.Indicate_(length, objects); if (errorCode < 0) { if ((errorCode & 0xfffff000L) == 0x80041000L) { ManagementException.ThrowWithExtendedInfo((ManagementStatus)errorCode); } else { Marshal.ThrowExceptionForHR(errorCode); } } } else { MTARequest request = new MTARequest(length, objects); lock (this.critSec) { if (!this.workerThreadInitialized) { Thread thread = new Thread(new ThreadStart(this.MTAWorkerThread2)) { IsBackground = true }; thread.SetApartmentState(ApartmentState.MTA); thread.Start(); this.workerThreadInitialized = true; } int index = this.reqList.Add(request); if (!this.doIndicate.Set()) { this.reqList.RemoveAt(index); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } request.doneIndicate.WaitOne(); if (request.exception != null) { throw request.exception; } } GC.KeepAlive(this); } }
// This method will create an instance of the requeted type in the MTA public static object CreateInMTA(Type type) { // If we are currently in the MTA, we can directly create the object if(IsNoContextMTA()) // Bug#110141 - Checking for MTA is not enough. We need to make sure we are not in a COM+ Context return Activator.CreateInstance(type); // We need to create the object in the MTA by using a worker thread // that lives in the MTA. Make sure only one person uses this worker // thread at a time MTARequest myReq = new MTARequest(type); int ndx; lock(critSec) { // Make sure worker thread is initialized if(workerThreadInitialized == false) { InitWorkerThread(); workerThreadInitialized = true; } ndx = reqList.Add(myReq); if( evtGo.Set() == false ) { reqList.RemoveAt(ndx); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } // release the lock so that worker thread can work on the request myReq.evtDone.WaitOne(); if (myReq.exception != null) { throw myReq.exception; } return myReq.createdObject; }
public void IndicateEvents(int length, IntPtr[] objects) { if (pSinkMTA == null) return; // // Checking for MTA is not enough. We need to make sure we are not in a COM+ Context // if (MTAHelper.IsNoContextMTA()) { // Sink lives in MTA int hresult = pSinkMTA.Indicate_(length, objects); if (hresult < 0) { if ((hresult & 0xfffff000) == 0x80041000) ManagementException.ThrowWithExtendedInfo((ManagementStatus)hresult); else Marshal.ThrowExceptionForHR(hresult); } } else { MTARequest myReq = new MTARequest(length,objects); int ndx; lock(critSec) { // Do it from worker thread if (workerThreadInitialized == false) { // We've never created worker thread Thread thread = new Thread(new ThreadStart(MTAWorkerThread2)); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.MTA); thread.Start(); workerThreadInitialized = true; } ndx = reqList.Add(myReq); if( doIndicate.Set() == false ) //SetEvent(hDoIndicate); { reqList.RemoveAt(ndx); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } myReq.doneIndicate.WaitOne(); //WaitForSingleObject(hDoneIndicate, -1); if (myReq.exception != null) { throw myReq.exception; } } GC.KeepAlive(this); }
public void IndicateEvents(int length, IntPtr[] objects) { if (this.pSinkMTA != null) { if (MTAHelper.IsNoContextMTA()) { int errorCode = this.pSinkMTA.Indicate_(length, objects); if (errorCode < 0) { if ((errorCode & 0xfffff000L) == 0x80041000L) { ManagementException.ThrowWithExtendedInfo((ManagementStatus) errorCode); } else { Marshal.ThrowExceptionForHR(errorCode); } } } else { MTARequest request = new MTARequest(length, objects); lock (this.critSec) { if (!this.workerThreadInitialized) { Thread thread = new Thread(new ThreadStart(this.MTAWorkerThread2)) { IsBackground = true }; thread.SetApartmentState(ApartmentState.MTA); thread.Start(); this.workerThreadInitialized = true; } int index = this.reqList.Add(request); if (!this.doIndicate.Set()) { this.reqList.RemoveAt(index); throw new ManagementException(RC.GetString("WORKER_THREAD_WAKEUP_FAILED")); } } request.doneIndicate.WaitOne(); if (request.exception != null) { throw request.exception; } } GC.KeepAlive(this); } }