public void Post_ToCopiedDispatcher_IsAsynchronous() { SynchronizationContext actionDispatcherSyncContext = null; using (ManualResetEvent completed = new ManualResetEvent(false)) using (ManualResetEvent wait = new ManualResetEvent(false)) using (ActionThread thread1 = new ActionThread()) using (ActionThread thread2 = new ActionThread()) { thread1.Start(); thread2.Start(); // Capture the second thread's SynchronizationContext and signal this thread when it's captured. actionDispatcherSyncContext = thread2.DoGet(() => { return SynchronizationContext.Current.CreateCopy(); }); // Have the first thread do an synchronous Post to the second thread and then trigger the "completed" event. // The action queued to the second thread will wait for the "wait" event. thread1.Do(() => { actionDispatcherSyncContext.Post((state) => { wait.WaitOne(); }, null); completed.Set(); }); bool completedSignalled = completed.WaitOne(100); Assert.IsTrue(completedSignalled, "ActionDispatcherSynchronizationContext.Post is not asynchronous"); wait.Set(); } }
public void InvalidBoundSyncedFunc_Invoked_DoesSync() { bool sawSync = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); var syncContext = new Util.LoggingSynchronizationContext(actionThreadSyncContext) { OnPost = () => { sawSync = true; }, OnSend = () => { sawSync = true; } }; var action = context.Bind(() => { return(13); }, syncContext, false); context.Reset(); int result = action(); Assert.IsTrue(sawSync, "Context did not use SyncContext for sync"); } }
public void SyncedActionWithFourArguments_Invoked_ReceivesParameters() { int arg1 = 0; int arg2 = 0; int arg3 = 0; int arg4 = 0; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" Action <int, int, int, int> action = thread.DoGet(() => { return(Sync.SynchronizeAction((int a1, int a2, int a3, int a4) => { arg1 = a1; arg2 = a2; arg3 = a3; arg4 = a4; })); }); action(13, 17, 19, 23); thread.Join(); Assert.AreEqual(13, arg1, "Action did not receive parameter"); Assert.AreEqual(17, arg2, "Action did not receive parameter"); Assert.AreEqual(19, arg3, "Action did not receive parameter"); Assert.AreEqual(23, arg4, "Action did not receive parameter"); } }
public void Send_ToCopiedDispatcher_IsSynchronous() { SynchronizationContext actionDispatcherSyncContext = null; using (ManualResetEvent completed = new ManualResetEvent(false)) using (ManualResetEvent wait = new ManualResetEvent(false)) using (ActionThread thread1 = new ActionThread()) using (ActionThread thread2 = new ActionThread()) { thread1.Start(); thread2.Start(); // Capture the second thread's SynchronizationContext and signal this thread when it's captured. actionDispatcherSyncContext = thread2.DoGet(() => { return(SynchronizationContext.Current.CreateCopy()); }); // Have the first thread do a synchronous Send to the second thread and then trigger the "completed" event. // The action queued to the second thread will wait for the "wait" event. thread1.Do(() => { actionDispatcherSyncContext.Send((state) => { wait.WaitOne(); }, null); completed.Set(); }); bool completedSignalled = completed.WaitOne(100); Assert.IsFalse(completedSignalled, "ActionDispatcherSynchronizationContext.Send is not synchronous"); wait.Set(); } }
public void BoundAsyncAction_Invoked_UsesSyncContext() { bool sawSync = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); var syncContext = new Util.LoggingSynchronizationContext(actionThreadSyncContext) { OnPost = () => { sawSync = true; }, OnSend = () => { sawSync = true; } }; var action = context.AsyncBind(() => { }, syncContext, false); action(); thread.Join(); Assert.IsTrue(sawSync, "Context did not use SyncContext for sync"); } }
public void SyncFunc_QueuedAfterStart_PreservesReturnValue() { using (ActionThread thread = new ActionThread()) { thread.Start(); object obj = thread.DoGet(() => { return(new object()); }); Assert.IsNotNull(obj, "ActionThread did not return result"); } }
public void ThreadPoolGSO_FromChildThread_DoesRequireInvoke() { using (ScopedSynchronizationContext x = new ScopedSynchronizationContext(new SynchronizationContext())) using (ActionThread thread = new ActionThread()) { GenericSynchronizingObject test = new GenericSynchronizingObject(); thread.Start(); bool invokeRequired = thread.DoGet(() => test.InvokeRequired); Assert.IsTrue(invokeRequired, "ThreadPool GenericSynchronizingObject does not require invoke from within a child thread"); } }
public void ActionThreadGSO_OutsideActionThread_DoesRequireInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); Assert.IsTrue(test.InvokeRequired, "GenericSynchronizingObject does not require invoke for ActionThread"); } }
public void ActionThreadGSO_WithinActionThread_DoesNotRequireInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture InvokeRequired from the ActionThread's context bool nestedInvokeRequired = thread.DoGet(() => { return(new GenericSynchronizingObject().InvokeRequired); }); Assert.IsFalse(nestedInvokeRequired, "GenericSynchronizingObject does require invoke within ActionThread"); } }
public void ActionThreadGSO_WithinActionThread_DoesNotRequireInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture InvokeRequired from the ActionThread's context bool nestedInvokeRequired = thread.DoGet(() => { return new GenericSynchronizingObject().InvokeRequired; }); Assert.IsFalse(nestedInvokeRequired, "GenericSynchronizingObject does require invoke within ActionThread"); } }
public void FailingAction_InvokedThroughActionThreadGSO_ThrowsTargetInvocationException() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); test.Invoke((MethodInvoker)(() => { throw new Exception(); }), null); } }
public void ActionThreadGSO_OutsideActionThread_DoesRequireInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); Assert.IsTrue(test.InvokeRequired, "GenericSynchronizingObject does not require invoke for ActionThread"); } }
public void SyncFunc_QueuedAfterStart_IsExecutedByThread() { int threadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); object obj = thread.DoGet(() => { threadId = Thread.CurrentThread.ManagedThreadId; return(new object()); }); Assert.AreEqual(thread.ManagedThreadId, threadId, "ActionThread ran in wrong thread context"); } }
public void AsyncResult_FromBeginInvoke_HasNullAsyncState() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); Assert.IsNull(result.AsyncState, "IAsyncResult.AsyncState is not used and should be null"); } }
public void AsyncResult_FromBeginInvoke_DidNotCompleteSynchronously() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); Assert.IsFalse(result.CompletedSynchronously, "IAsyncResult.CompletedSynchronously is not used and should be false"); } }
public void SyncContext_FromInsideAction_IsActionDispatcherSyncContext() { SynchronizationContext actionThreadSyncContext = null; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); Assert.IsInstanceOfType(actionThreadSyncContext, typeof(ActionDispatcherSynchronizationContext), "ActionThread did not provide an ActionDispatcherSynchronizationContext"); } }
public void AsyncResultWaitHandle_FromBeginInvoke_IsWaitable() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); bool signalled = result.AsyncWaitHandle.WaitOne(100); Assert.IsTrue(signalled, "AsyncWaitHandle should be signalled"); } }
static void Main() { using (ActionThread actionThread = new ActionThread()) { actionThread.Start(); Console.WriteLine("Console thread ID: " + Thread.CurrentThread.ManagedThreadId); // Any delegates passed to ActionThread.DoGet are run by that ActionThread (synchronously) int actionThreadID = actionThread.DoGet(() => Thread.CurrentThread.ManagedThreadId); Console.WriteLine("ActionThread thread ID: " + actionThreadID); } }
public void AsyncResult_AfterEndInvoke_ReturnsImmediatelyFromEndInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); test.EndInvoke(result); test.EndInvoke(result); } }
public void Action_InvokedThroughActionThreadGSO_RunsOnTheActionThread() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); int actionThreadId = Thread.CurrentThread.ManagedThreadId; test.Invoke((MethodInvoker)(() => { actionThreadId = Thread.CurrentThread.ManagedThreadId; }), null); Assert.AreEqual(thread.ManagedThreadId, actionThreadId, "GenericSynchronizingObject.Invoke did not synchronize"); } }
public void Action_InvokedThroughActionThreadGSO_Runs() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); test.Invoke((MethodInvoker)(() => { sawAction = true; }), null); Assert.AreEqual(true, sawAction, "GenericSynchronizingObject.Invoke did not execute action"); } }
public void Action_BeginInvokeThroughActionThreadGSO_RunsOnTheActionThread() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); int actionThreadId = Thread.CurrentThread.ManagedThreadId; IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { actionThreadId = Thread.CurrentThread.ManagedThreadId; }), null); test.EndInvoke(result); Assert.AreEqual(thread.ManagedThreadId, actionThreadId, "GenericSynchronizingObject.BeginInvoke did not synchronize"); } }
public void AsyncResultWaitHandle_FromBeginInvoke_IsPollable() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); while (!result.IsCompleted) { Thread.Sleep(20); } } }
public void Action_InvokedThroughActionThreadGSO_ReceivesParameters() { object parameter = new object(); object argument = null; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); test.Invoke((Action <object>)((arg) => { argument = arg; }), new [] { parameter }); Assert.AreSame(parameter, argument, "GenericSynchronizingObject.Invoke did not pass parameter"); } }
public void InvalidBoundSyncedFunc_Invoked_ReturnsDefault() { using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); var action = context.Bind(() => { return(13); }, actionThreadSyncContext, false); context.Reset(); int result = action(); Assert.AreEqual(0, result, "Invalid Func returned a non-default value"); } }
public void Action_BeginInvokeThroughActionThreadGSO_Runs() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { sawAction = true; }), null); test.EndInvoke(result); Assert.IsTrue(sawAction, "GenericSynchronizingObject.BeginInvoke did not execute action"); } }
public void SyncContext_FromInsideAction_SendsToSameThread() { int threadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); // Use the SynchronizationContext to give the ActionThread more work to do actionThreadSyncContext.Send((state) => { threadId = Thread.CurrentThread.ManagedThreadId; }, null); Assert.AreEqual(thread.ManagedThreadId, threadId, "ActionThread ran in wrong thread context"); } }
public void Action_BeginInvokeThroughActionThreadGSO_Runs() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return(new GenericSynchronizingObject()); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { sawAction = true; }), null); test.EndInvoke(result); Assert.IsTrue(sawAction, "GenericSynchronizingObject.BeginInvoke did not execute action"); } }
public void ActionWithThreeArguments_AfterSync_HasNotRun() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" Action<int, int, int> action = thread.DoGet(() => { return Sync.SynchronizeAction((int a1, int a2, int a3) => { sawAction = true; }); }); // The action should be run in the context of the ActionThread Assert.IsFalse(sawAction, "Action should not have run already"); } }
public void WaitOrTimerCallback_AfterSync_HasNotRun() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" WaitOrTimerCallback action = thread.DoGet(() => { return(Sync.SynchronizeWaitOrTimerCallback((a1, a2) => { sawAction = true; })); }); // The action should be run in the context of the ActionThread Assert.IsFalse(sawAction, "Action should not have run already"); } }
public void ActionWithOneArgument_AfterSync_HasNotRun() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" Action <int> action = thread.DoGet(() => { return(Sync.SynchronizeAction((int a1) => { sawAction = true; })); }); // The action should be run in the context of the ActionThread Assert.IsFalse(sawAction, "Action should not have run already"); } }
public void BoundSyncedFunc_Invoked_ExecutesSynchronized() { int sawActionThread = Thread.CurrentThread.ManagedThreadId; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); var action = context.Bind(() => { sawActionThread = Thread.CurrentThread.ManagedThreadId; return(13); }, actionThreadSyncContext); int result = action(); Assert.AreEqual(thread.ManagedThreadId, sawActionThread, "Bound action was not synchronized"); } }
public void InvalidBoundSyncedFunc_Invoked_DoesNotExecute() { int sawActionThread = Thread.CurrentThread.ManagedThreadId; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return(SynchronizationContext.Current); }); var action = context.Bind(() => { sawActionThread = Thread.CurrentThread.ManagedThreadId; return(13); }, actionThreadSyncContext, false); context.Reset(); int result = action(); Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, sawActionThread, "Invalid action should not run"); } }
public void SyncedActionWithOneArgument_Invoked_ReceivesParameters() { int arg1 = 0; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" Action <int> action = thread.DoGet(() => { return(Sync.SynchronizeAction((int a1) => { arg1 = a1; })); }); action(13); thread.Join(); Assert.AreEqual(13, arg1, "Action did not receive parameter"); } }
public void SyncedWaitOrTimerCallback_Invoked_RunsSynchronized() { int actionThreadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" WaitOrTimerCallback action = thread.DoGet(() => { return(Sync.SynchronizeWaitOrTimerCallback((a1, a2) => { actionThreadId = Thread.CurrentThread.ManagedThreadId; })); }); // The action should be run in the context of the ActionThread action(null, false); thread.Join(); Assert.AreEqual(thread.ManagedThreadId, actionThreadId, "Action did not run synchronized"); } }
public void SyncedActionWithOneArgument_Invoked_RunsSynchronized() { int actionThreadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" Action <int> action = thread.DoGet(() => { return(Sync.SynchronizeAction((int a1) => { actionThreadId = Thread.CurrentThread.ManagedThreadId; })); }); // The action should be run in the context of the ActionThread action(13); thread.Join(); Assert.AreEqual(thread.ManagedThreadId, actionThreadId, "Action did not run synchronized"); } }
public void BoundAsyncAction_Invoked_DecrementsSyncContextOperationCount() { bool sawOperationCompleted = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var syncContext = new LoggingSynchronizationContext(actionThreadSyncContext) { OnOperationCompleted = () => { sawOperationCompleted = true; } }; var action = context.AsyncBind(() => { }, syncContext, false); action(); thread.Join(); Assert.IsFalse(sawOperationCompleted, "Context decremented operation count"); } }
public void AsyncResult_AfterWait_ReturnsImmediatelyFromEndInvoke() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); result.AsyncWaitHandle.WaitOne(100); test.EndInvoke(result); } }
public void AsyncResult_FromBeginInvoke_DidNotCompleteSynchronously() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); Assert.IsFalse(result.CompletedSynchronously, "IAsyncResult.CompletedSynchronously is not used and should be false"); } }
public void AsyncResult_FromBeginInvoke_HasNullAsyncState() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); Assert.IsNull(result.AsyncState, "IAsyncResult.AsyncState is not used and should be null"); } }
public void FailingAction_InvokedThroughActionThreadGSO_PreservesExceptionAsInnerException() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); Exception errorToThrow = new MyException(); Exception innerErrorCaught = null; try { test.Invoke((MethodInvoker)(() => { throw errorToThrow; }), null); } catch (TargetInvocationException ex) { innerErrorCaught = ex.InnerException; } Assert.AreSame(errorToThrow, innerErrorCaught, "Exception not preserved"); } }
public void InvalidBoundSyncedFunc_Invoked_ReturnsDefault() { using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var action = context.Bind(() => { return 13; }, actionThreadSyncContext, false); context.Reset(); int result = action(); Assert.AreEqual(0, result, "Invalid Func returned a non-default value"); } }
public void WaitOrTimerCallback_AfterSync_HasNotRun() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" WaitOrTimerCallback action = thread.DoGet(() => { return Sync.SynchronizeWaitOrTimerCallback((a1, a2) => { sawAction = true; }); }); // The action should be run in the context of the ActionThread Assert.IsFalse(sawAction, "Action should not have run already"); } }
public void AsyncResultWaitHandle_FromBeginInvoke_IsPollable() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); while (!result.IsCompleted) { Thread.Sleep(20); } } }
public void SyncContext_FromInsideAction_SendsToSameThread() { int threadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); // Use the SynchronizationContext to give the ActionThread more work to do actionThreadSyncContext.Send((state) => { threadId = Thread.CurrentThread.ManagedThreadId; }, null); Assert.AreEqual(thread.ManagedThreadId, threadId, "ActionThread ran in wrong thread context"); } }
public void SyncedWaitOrTimerCallback_Invoked_RunsSynchronized() { int actionThreadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" WaitOrTimerCallback action = thread.DoGet(() => { return Sync.SynchronizeWaitOrTimerCallback((a1, a2) => { actionThreadId = Thread.CurrentThread.ManagedThreadId; }); }); // The action should be run in the context of the ActionThread action(null, false); thread.Join(); Assert.AreEqual(thread.ManagedThreadId, actionThreadId, "Action did not run synchronized"); } }
public void BoundSyncedAction_Invoked_UsesSyncContext() { bool sawSync = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var syncContext = new LoggingSynchronizationContext(actionThreadSyncContext) { OnPost = () => { sawSync = true; }, OnSend = () => { sawSync = true; } }; var action = context.Bind(() => { }, syncContext, false); action(); Assert.IsTrue(sawSync, "Context did not use SyncContext for sync"); } }
public void BoundSyncedFunc_Invoked_IncrementsSyncContextOperationCount() { bool sawOperationStarted = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var syncContext = new LoggingSynchronizationContext(actionThreadSyncContext) { OnOperationStarted = () => { sawOperationStarted = true; } }; var action = context.Bind(() => { return 13; }, syncContext, false); int result = action(); Assert.IsFalse(sawOperationStarted, "Context incremented operation count"); } }
public void BoundAsyncAction_Invoked_ExecutesSynchronized() { int sawActionThread = Thread.CurrentThread.ManagedThreadId; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var action = context.AsyncBind(() => { sawActionThread = Thread.CurrentThread.ManagedThreadId; }, actionThreadSyncContext); action(); thread.Join(); Assert.AreEqual(thread.ManagedThreadId, sawActionThread, "Bound action was not synchronized"); } }
public void InvalidBoundSyncedFunc_Invoked_DoesNotExecute() { int sawActionThread = Thread.CurrentThread.ManagedThreadId; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var action = context.Bind(() => { sawActionThread = Thread.CurrentThread.ManagedThreadId; return 13; }, actionThreadSyncContext, false); context.Reset(); int result = action(); Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, sawActionThread, "Invalid action should not run"); } }
public void AsyncResultWaitHandle_FromBeginInvoke_IsWaitable() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject ISynchronizeInvoke test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((MethodInvoker)(() => { }), null); bool signalled = result.AsyncWaitHandle.WaitOne(100); Assert.IsTrue(signalled, "AsyncWaitHandle should be signalled"); } }
public void SyncContext_FromInsideAction_IsActionDispatcherSyncContext() { SynchronizationContext actionThreadSyncContext = null; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); Assert.IsInstanceOfType(actionThreadSyncContext, typeof(ActionDispatcherSynchronizationContext), "ActionThread did not provide an ActionDispatcherSynchronizationContext"); } }
public void Send_IsSynchronous() { SynchronizationContext actionDispatcherSyncContext = null; using (ManualResetEvent completed = new ManualResetEvent(false)) using (ManualResetEvent wait = new ManualResetEvent(false)) using (ActionThread thread1 = new ActionThread()) using (ActionThread thread2 = new ActionThread()) { thread1.Start(); thread2.Start(); // Capture the second thread's SynchronizationContext. actionDispatcherSyncContext = thread2.DoGet(() => { return SynchronizationContext.Current; }); // Have the first thread do a synchronous Send to the second thread and then trigger the "completed" event. // The action queued to the second thread will wait for the "wait" event. thread1.Do(() => { actionDispatcherSyncContext.Send((state) => { wait.WaitOne(); }, null); completed.Set(); }); bool completedSignalled = completed.WaitOne(100); Assert.IsFalse(completedSignalled, "ActionDispatcherSynchronizationContext.Send is not synchronous"); wait.Set(); } }
public void Action_BeginInvokeThroughGSO_ReceivesParameters() { object parameter = new object(); object argument = null; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); IAsyncResult result = test.BeginInvoke((Action<object>)((arg) => { argument = arg; }), new [] { parameter }); test.EndInvoke(result); Assert.AreSame(parameter, argument, "GenericSynchronizingObject.BeginInvoke did not pass parameter"); } }
public void Action_InvokedThroughActionThreadGSO_Runs() { bool sawAction = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); test.Invoke((MethodInvoker)(() => { sawAction = true; }), null); Assert.AreEqual(true, sawAction, "GenericSynchronizingObject.Invoke did not execute action"); } }
public void FailingAction_InvokedThroughActionThreadGSO_ThrowsTargetInvocationException() { using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture GenericSynchronizingObject GenericSynchronizingObject test = thread.DoGet(() => { return new GenericSynchronizingObject(); }); test.Invoke((MethodInvoker)(() => { throw new Exception(); }), null); } }
public void SyncFunc_QueuedAfterStart_IsExecutedByThread() { int threadId = Thread.CurrentThread.ManagedThreadId; using (ActionThread thread = new ActionThread()) { thread.Start(); object obj = thread.DoGet(() => { threadId = Thread.CurrentThread.ManagedThreadId; return new object(); }); Assert.AreEqual(thread.ManagedThreadId, threadId, "ActionThread ran in wrong thread context"); } }
public void InvalidBoundSyncedFunc_Invoked_DoesSync() { bool sawSync = false; using (CallbackContext context = new CallbackContext()) using (ActionThread thread = new ActionThread()) { thread.Start(); // Capture the thread's SynchronizationContext and signal this thread when it's captured. SynchronizationContext actionThreadSyncContext = thread.DoGet(() => { return SynchronizationContext.Current; }); var syncContext = new LoggingSynchronizationContext(actionThreadSyncContext) { OnPost = () => { sawSync = true; }, OnSend = () => { sawSync = true; } }; var action = context.Bind(() => { return 13; }, syncContext, false); context.Reset(); int result = action(); Assert.IsTrue(sawSync, "Context did not use SyncContext for sync"); } }
public void SyncFunc_QueuedAfterStart_PreservesReturnValue() { using (ActionThread thread = new ActionThread()) { thread.Start(); object obj = thread.DoGet(() => { return new object(); }); Assert.IsNotNull(obj, "ActionThread did not return result"); } }
public void SyncedWaitOrTimerCallback_Invoked_ReceivesParameter() { object parameter1 = new object(); object arg1 = null; bool arg2 = false; using (ActionThread thread = new ActionThread()) { thread.Start(); // Have the ActionThread set "action" WaitOrTimerCallback action = thread.DoGet(() => { return Sync.SynchronizeWaitOrTimerCallback((a1, a2) => { arg1 = a1; arg2 = a2; }); }); action(parameter1, true); thread.Join(); Assert.AreSame(parameter1, arg1, "Action did not receive parameter"); Assert.IsTrue(arg2, "Action did not receive parameter"); } }