/// <summary> /// Marshals the Task as an IAsyncResult, using the supplied callback and state /// to implement the APM pattern. /// </summary> /// <param name="task">The Task to be marshaled.</param> /// <param name="callback">The callback to be invoked upon completion.</param> /// <param name="state">The state to be stored in the IAsyncResult.</param> /// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns> public static IAsyncResult Begin(Task task, AsyncCallback callback, object state) { Debug.Assert(task != null); // If the task has already completed, then since the Task's CompletedSynchronously==false // and we want it to be true, we need to create a new IAsyncResult. (We also need the AsyncState to match.) IAsyncResult asyncResult; if (task.IsCompleted) { // Synchronous completion. asyncResult = new TaskWrapperAsyncResult(task, state, true); if (callback != null) { callback(asyncResult); } } else { // For asynchronous completion we need to schedule a callback. Whether we can use the Task as the IAsyncResult // depends on whether the Task's AsyncState has reference equality with the requested state. asyncResult = task.AsyncState == state ? (IAsyncResult)task : new TaskWrapperAsyncResult(task, state, completedSynchronously: false); if (callback != null) { InvokeCallbackWhenTaskCompletes(task, callback, asyncResult); } } return(asyncResult); }
public void ExecuteTaskPreservesState() { // Arrange TaskAsyncActionDescriptor actionDescriptor = GetActionDescriptor( GetExecuteControllerMethodInfo("SimpleTask") ); Dictionary <string, object> parameters = new Dictionary <string, object>() { { "doWork", true } }; ControllerContext controllerContext = GetControllerContext(); // Act TaskWrapperAsyncResult result = (TaskWrapperAsyncResult)actionDescriptor.BeginExecute( GetControllerContext(), parameters, callback: null, state: "state" ); // Assert Assert.Equal("state", result.AsyncState); }
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { Task task = ProcessRequestAsync(new HttpContextWrapper(context)); var retVal = new TaskWrapperAsyncResult(task, extraData); if (task == null) { // No task, so just let ASP.NET deal with it return(null); } if (cb != null) { // The callback needs the same argument that the Begin method returns, which is our special wrapper, not the original Task. task.ContinueWith(_ => cb(retVal)); } return(retVal); }
public void PropertiesHaveCorrectValues() { // Arrange Mock<MyTask> mockTask = new Mock<MyTask>(); WaitHandle waitHandle = new Mock<WaitHandle>().Object; mockTask.Setup(o => o.AsyncState).Returns(10); mockTask.Setup(o => o.AsyncWaitHandle).Returns(waitHandle); mockTask.Setup(o => o.CompletedSynchronously).Returns(true); mockTask.Setup(o => o.IsCompleted).Returns(true); // Act TaskWrapperAsyncResult taskWrapper = new TaskWrapperAsyncResult(mockTask.Object, asyncState: 20); // Assert Assert.Equal(20, taskWrapper.AsyncState); Assert.Equal(waitHandle, taskWrapper.AsyncWaitHandle); Assert.True(taskWrapper.CompletedSynchronously); Assert.True(taskWrapper.IsCompleted); Assert.Equal(mockTask.Object, taskWrapper.Task); }
public void PropertiesHaveCorrectValues() { // Arrange Mock <MyTask> mockTask = new Mock <MyTask>(); WaitHandle waitHandle = new Mock <WaitHandle>().Object; mockTask.Setup(o => o.AsyncState).Returns(10); mockTask.Setup(o => o.AsyncWaitHandle).Returns(waitHandle); mockTask.Setup(o => o.CompletedSynchronously).Returns(true); mockTask.Setup(o => o.IsCompleted).Returns(true); // Act TaskWrapperAsyncResult taskWrapper = new TaskWrapperAsyncResult(mockTask.Object, asyncState: 20); // Assert Assert.Equal(20, taskWrapper.AsyncState); Assert.Equal(waitHandle, taskWrapper.AsyncWaitHandle); Assert.True(taskWrapper.CompletedSynchronously); Assert.True(taskWrapper.IsCompleted); Assert.Equal(mockTask.Object, taskWrapper.Task); }