From 75321c3e3689e0d1aedf5c07f62d6bdc00cfd23d Mon Sep 17 00:00:00 2001 From: Frederik Carlier <frederik.carlier@quamotion.mobi> Date: Wed, 3 Aug 2016 23:52:40 +0200 Subject: [PATCH] SendAsync: Add the ability to cancel the async task --- source/ChromeDevTools/ChromeSession.cs | 18 +++++++++--------- .../ChromeDevTools/ChromeSessionExtensions.cs | 18 ++++++++++++++++++ source/ChromeDevTools/IChromeSession.cs | 5 +++-- .../MasterDevs.ChromeDevTools.csproj | 1 + 4 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 source/ChromeDevTools/ChromeSessionExtensions.cs diff --git a/source/ChromeDevTools/ChromeSession.cs b/source/ChromeDevTools/ChromeSession.cs index 087c4d5..bb6ad0f 100644 --- a/source/ChromeDevTools/ChromeSession.cs +++ b/source/ChromeDevTools/ChromeSession.cs @@ -17,7 +17,7 @@ namespace MasterDevs.ChromeDevTools private IEventFactory _eventFactory; private ManualResetEvent _openEvent = new ManualResetEvent(false); private ManualResetEvent _publishEvent = new ManualResetEvent(false); - private ConcurrentDictionary<long, ManualResetEvent> _requestWaitHandles = new ConcurrentDictionary<long, ManualResetEvent>(); + private ConcurrentDictionary<long, ManualResetEventSlim> _requestWaitHandles = new ConcurrentDictionary<long, ManualResetEventSlim>(); private ICommandResponseFactory _responseFactory; private ConcurrentDictionary<long, ICommandResponse> _responses = new ConcurrentDictionary<long, ICommandResponse>(); private WebSocket _webSocket; @@ -73,16 +73,16 @@ namespace MasterDevs.ChromeDevTools }); } - public Task<ICommandResponse> SendAsync<T>() + public Task<ICommandResponse> SendAsync<T>(CancellationToken cancellationToken) { var command = _commandFactory.Create<T>(); - return SendCommand(command); + return SendCommand(command, cancellationToken); } - public Task<ICommandResponse> SendAsync<T>(T parameter) + public Task<ICommandResponse> SendAsync<T>(T parameter, CancellationToken cancellationToken) { var command = _commandFactory.Create(parameter); - return SendCommand(command); + return SendCommand(command, cancellationToken); } public void Subscribe<T>(Action<T> handler) where T : class @@ -136,7 +136,7 @@ namespace MasterDevs.ChromeDevTools private void HandleResponse(ICommandResponse response) { if (null == response) return; - ManualResetEvent requestMre; + ManualResetEventSlim requestMre; if (_requestWaitHandles.TryGetValue(response.Id, out requestMre)) { _responses.AddOrUpdate(response.Id, id => response, (key, value) => response); @@ -156,7 +156,7 @@ namespace MasterDevs.ChromeDevTools } } - private Task<ICommandResponse> SendCommand(Command command) + private Task<ICommandResponse> SendCommand(Command command, CancellationToken cancellationToken) { var settings = new JsonSerializerSettings { @@ -164,13 +164,13 @@ namespace MasterDevs.ChromeDevTools NullValueHandling = NullValueHandling.Ignore, }; var requestString = JsonConvert.SerializeObject(command, settings); - var requestResetEvent = new ManualResetEvent(false); + var requestResetEvent = new ManualResetEventSlim(false); _requestWaitHandles.AddOrUpdate(command.Id, requestResetEvent, (id, r) => requestResetEvent); return Task.Run(() => { EnsureInit(); _webSocket.Send(requestString); - requestResetEvent.WaitOne(); + requestResetEvent.Wait(cancellationToken); ICommandResponse response = null; _responses.TryRemove(command.Id, out response); _requestWaitHandles.TryRemove(command.Id, out requestResetEvent); diff --git a/source/ChromeDevTools/ChromeSessionExtensions.cs b/source/ChromeDevTools/ChromeSessionExtensions.cs new file mode 100644 index 0000000..b0817f8 --- /dev/null +++ b/source/ChromeDevTools/ChromeSessionExtensions.cs @@ -0,0 +1,18 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace MasterDevs.ChromeDevTools +{ + public static class ChromeSessionExtensions + { + public static Task<ICommandResponse> SendAsync<T>(this IChromeSession session, T parameter) + { + return session.SendAsync<T>(parameter, CancellationToken.None); + } + + public static Task<ICommandResponse> SendAsync<T>(this IChromeSession session) + { + return session.SendAsync<T>(CancellationToken.None); + } + } +} diff --git a/source/ChromeDevTools/IChromeSession.cs b/source/ChromeDevTools/IChromeSession.cs index 7840557..e5ae25f 100644 --- a/source/ChromeDevTools/IChromeSession.cs +++ b/source/ChromeDevTools/IChromeSession.cs @@ -1,13 +1,14 @@ using System; +using System.Threading; using System.Threading.Tasks; namespace MasterDevs.ChromeDevTools { public interface IChromeSession { - Task<ICommandResponse> SendAsync<T>(T parameter); + Task<ICommandResponse> SendAsync<T>(T parameter, CancellationToken cancellationToken); - Task<ICommandResponse> SendAsync<T>(); + Task<ICommandResponse> SendAsync<T>(CancellationToken cancellationToken); void Subscribe<T>(Action<T> handler) where T : class; } diff --git a/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj b/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj index c8c40e0..46662a5 100644 --- a/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj +++ b/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj @@ -50,6 +50,7 @@ <Compile Include="ChromeProcessFactory.cs" /> <Compile Include="ChromeProcess.cs" /> <Compile Include="ChromeSession.cs" /> + <Compile Include="ChromeSessionExtensions.cs" /> <Compile Include="ChromeSessionFactory.cs" /> <Compile Include="Command.cs" /> <Compile Include="CommandAttribute.cs" /> -- GitLab