43 lines
1.8 KiB
C#
43 lines
1.8 KiB
C#
|
//------------------------------------------------------------------------------
|
|||
|
// <copyright file="PageAsyncTaskApm.cs" company="Microsoft">
|
|||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|||
|
// </copyright>
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
|
|||
|
namespace System.Web.UI {
|
|||
|
using System;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
// Represents an IPageAsyncTask that follows APM (Begin / End)
|
|||
|
|
|||
|
internal sealed class PageAsyncTaskApm : IPageAsyncTask {
|
|||
|
|
|||
|
private readonly BeginEventHandler _beginHandler;
|
|||
|
private readonly EndEventHandler _endHandler;
|
|||
|
private readonly object _state;
|
|||
|
|
|||
|
public PageAsyncTaskApm(BeginEventHandler beginHandler, EndEventHandler endHandler, object state) {
|
|||
|
_beginHandler = beginHandler;
|
|||
|
_endHandler = endHandler;
|
|||
|
_state = state;
|
|||
|
}
|
|||
|
|
|||
|
public async Task ExecuteAsync(object sender, EventArgs e, CancellationToken cancellationToken) {
|
|||
|
// The CancellationToken is ignored in APM since every call to Begin must be matched by
|
|||
|
// a call to End, otherwise memory leaks and other badness can occur.
|
|||
|
|
|||
|
// The reason we don't use TaskFactory.FromAsync is that we need the end handler to execute
|
|||
|
// within the current synchronization context, but FromAsync doesn't make that guarantee.
|
|||
|
|
|||
|
// The callback that marks the TaskCompletionSource as complete can execute synchronously or asynchronously.
|
|||
|
TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>();
|
|||
|
IAsyncResult asyncResult = _beginHandler(sender, e, _ => { taskCompletionSource.SetResult(null); }, _state);
|
|||
|
|
|||
|
await taskCompletionSource.Task;
|
|||
|
_endHandler(asyncResult);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|