private static SynchronizationContext GetWinRTContext() { // Optimization: WinRT dispatchers are supported for STA and ASTA apartment types only if (Thread.GetCurrentApartmentType() != Thread.ApartmentType.STA) { return(null); } object dispatcher = WinRTInterop.Callbacks.GetCurrentWinRTDispatcher(); if (dispatcher == null) { return(null); } return(s_winRTContextCache.GetValue(dispatcher, _dispatcher => new WinRTSynchronizationContext(_dispatcher))); }
private static unsafe int WaitForMultipleObjectsIgnoringSyncContext(IntPtr *pHandles, int numHandles, bool waitAll, int millisecondsTimeout) { Debug.Assert(millisecondsTimeout >= -1); // // In the CLR, we use CoWaitForMultipleHandles to pump messages while waiting in an STA. In that case, we cannot use WAIT_ALL. // That's because the wait would only be satisfied if a message arrives while the handles are signalled. // if (waitAll) { if (numHandles == 1) { waitAll = false; } else if (Thread.GetCurrentApartmentType() == Thread.ApartmentType.STA) { throw new NotSupportedException(SR.NotSupported_WaitAllSTAThread); } } Thread currentThread = Thread.CurrentThread; currentThread.SetWaitSleepJoinState(); int result; if (Thread.ReentrantWaitsEnabled) { Debug.Assert(!waitAll); result = RuntimeImports.RhCompatibleReentrantWaitAny(false, millisecondsTimeout, numHandles, pHandles); } else { result = (int)Interop.Kernel32.WaitForMultipleObjectsEx((uint)numHandles, (IntPtr)pHandles, waitAll, (uint)millisecondsTimeout, false); } currentThread.ClearWaitSleepJoinState(); if (result == Interop.Kernel32.WAIT_FAILED) { int errorCode = Interop.mincore.GetLastError(); if (waitAll && errorCode == Interop.Errors.ERROR_INVALID_PARAMETER) { // Check for duplicate handles. This is a brute force O(n^2) search, which is intended since the typical // array length is short enough that this would actually be faster than using a hash set. Also, the worst // case is not so bad considering that the array length is limited by // <see cref="WaitHandle.MaxWaitHandles"/>. for (int i = 1; i < numHandles; ++i) { IntPtr handle = pHandles[i]; for (int j = 0; j < i; ++j) { if (pHandles[j] == handle) { throw new DuplicateWaitObjectException("waitHandles[" + i + ']'); } } } } ThrowWaitFailedException(errorCode); } return(result); }