diff --git a/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs b/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs index 7d09d1b..c7d44cb 100644 --- a/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs +++ b/Asterisk.2013/Asterisk.NET/Manager/ManagerConnection.cs @@ -9,6 +9,7 @@ using System.Text; using System.Collections.Generic; using System.Reflection; using AsterNET.IO; +using System.Threading.Tasks; namespace AsterNET.Manager { @@ -1345,13 +1346,13 @@ namespace AsterNET.Manager /// action to send /// timeout in milliseconds /// - public Response.ManagerResponse SendAction(ManagerAction action, int timeOut) + public Response.ManagerResponse SendAction(ManagerAction action, int timeout) { AutoResetEvent autoEvent = new AutoResetEvent(false); ResponseHandler handler = new ResponseHandler(action, autoEvent); int hash = SendAction(action, handler); - bool result = autoEvent.WaitOne(timeOut <= 0 ? -1 : timeOut, true); + bool result = autoEvent.WaitOne(timeout <= 0 ? -1 : timeout, true); RemoveResponseHandler(handler); @@ -1362,7 +1363,13 @@ namespace AsterNET.Manager #endregion #region SendAction(action, responseHandler) - public int SendAction(ManagerAction action, ResponseHandler responseHandler) + /// + /// Send action ans with timeout (milliseconds) + /// + /// action to send + /// Response Handler + /// + public int SendAction(ManagerAction action, IResponseHandler responseHandler) { if (action == null) throw new ArgumentException("Unable to send action: action is null."); @@ -1385,6 +1392,42 @@ namespace AsterNET.Manager } #endregion + + + #region SendActionAsync(action) + /// + /// Asynchronously send Action async with default timeout. + /// + /// action to send + public Task SendActionAsync(ManagerAction action) + { + return SendActionAsync(action, null); + } + #endregion + + #region SendActionAsync(action, timeout) + /// + /// Asynchronously send Action async. + /// + /// action to send + /// cancellation Token + public Task SendActionAsync(ManagerAction action, CancellationTokenSource cancellationToken) + { + var handler = new TaskResponseHandler(action); + var source = handler.TaskCompletionSource; + + SendAction(action, handler); + + if (cancellationToken != null) + cancellationToken.Token.Register(() => { source.TrySetCanceled(); }); + + return source.Task.ContinueWith(x => + { + RemoveResponseHandler(handler); + return x.Result; + }); + } + #endregion #region SendEventGeneratingAction(action) public ResponseEvents SendEventGeneratingAction(ManagerActionEvent action) { @@ -1451,7 +1494,11 @@ namespace AsterNET.Manager responseEventHandlers[handler.Hash] = handler; } - internal void RemoveResponseHandler(IResponseHandler handler) + /// + /// Delete an instance of a class from handlers list. + /// + /// Class instance . + public void RemoveResponseHandler(IResponseHandler handler) { int hash = handler.Hash; if (hash != 0) @@ -1468,7 +1515,6 @@ namespace AsterNET.Manager if (responseEventHandlers.ContainsKey(hash)) responseEventHandlers.Remove(hash); } - private IResponseHandler GetRemoveResponseHandler(int hash) { IResponseHandler handler = null; diff --git a/Asterisk.2013/Asterisk.NET/Manager/ResponseHandlers/TaskResponseHandler.cs b/Asterisk.2013/Asterisk.NET/Manager/ResponseHandlers/TaskResponseHandler.cs new file mode 100644 index 0000000..d96ccbf --- /dev/null +++ b/Asterisk.2013/Asterisk.NET/Manager/ResponseHandlers/TaskResponseHandler.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using AsterNET.Manager.Action; + +namespace AsterNET.Manager.Response +{ + /// + /// + /// + public class TaskResponseHandler : IResponseHandler + { + public TaskResponseHandler(ManagerAction action) + { + TaskCompletionSource = new TaskCompletionSource(); + Action = action; + } + + public TaskCompletionSource TaskCompletionSource { get; } + + public ManagerAction Action { get; } + + public int Hash { get; set; } + + public void HandleResponse(ManagerResponse response) + { + TaskCompletionSource.TrySetResult(response); + } + + public void Free() { } + } +}