Merge pull request #171 from moldypenguins/async/await

async/await
Implements `SendActionAsync`.
This commit is contained in:
Deantwo 2018-09-22 00:08:05 +02:00 committed by GitHub
commit e27e2ea729
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 5 deletions

View file

@ -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
/// <param name="action">action to send</param>
/// <param name="timeout">timeout in milliseconds</param>
/// <returns></returns>
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)
/// <summary>
/// Send action ans with timeout (milliseconds)
/// </summary>
/// <param name="action">action to send</param>
/// <param name="responseHandler">Response Handler</param>
/// <returns></returns>
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)
/// <summary>
/// Asynchronously send Action async with default timeout.
/// </summary>
/// <param name="action">action to send</param>
public Task<ManagerResponse> SendActionAsync(ManagerAction action)
{
return SendActionAsync(action, null);
}
#endregion
#region SendActionAsync(action, timeout)
/// <summary>
/// Asynchronously send Action async.
/// </summary>
/// <param name="action">action to send</param>
/// <param name="cancellationToken">cancellation Token</param>
public Task<ManagerResponse> 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)
/// <summary>
/// Delete an instance of a class <see cref="IResponseHandler"/> from handlers list.
/// </summary>
/// <param name="handler">Class instance <see cref="IResponseHandler"/>.</param>
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;

View file

@ -0,0 +1,30 @@
using System.Threading.Tasks;
using AsterNET.Manager.Action;
namespace AsterNET.Manager.Response
{
/// <summary>
///
/// </summary>
public class TaskResponseHandler : IResponseHandler
{
public TaskResponseHandler(ManagerAction action)
{
TaskCompletionSource = new TaskCompletionSource<ManagerResponse>();
Action = action;
}
public TaskCompletionSource<ManagerResponse> TaskCompletionSource { get; }
public ManagerAction Action { get; }
public int Hash { get; set; }
public void HandleResponse(ManagerResponse response)
{
TaskCompletionSource.TrySetResult(response);
}
public void Free() { }
}
}