Reputation: 3422
I have created scan method using Scandit framework. Since I am using Xamarin.Forms there is no option to await the scan. Scandit prepared the callback as result of scanning. I would like to wrap that into one method which could be used with awaiter.
There is what I have done:
public async Task<Operation<string>> ScanAsync(CancellationToken cancellationToken = default(CancellationToken))
{
try
{
_codeScannedTcs = new TaskCompletionSource<Operation<string>>();
ScanditService.BarcodePicker.DidScan += OnScanFinished;
await ScanditService.BarcodePicker.StartScanningAsync();
var result = await Task.WhenAny(_codeScannedTcs.Task);
return result.Result;
}
catch (TaskCanceledException)
{
return Operation<string>.FailedOperation("A task was canceled");
}
catch (Exception ex)
{
return Operation<string>.FailedOperation(ex.Message);
}
finally
{
_codeScannedTcs = null;
ScanditService.BarcodePicker.DidScan -= OnScanFinished;
}
}
How in that situation I can use the cancellation token to break the scanning in any time?
Upvotes: 0
Views: 144
Reputation: 883
I've used this code in the past:
/// <summary>
/// Allows the code waiting for an async operation to stop waiting when the cancellation token is set.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="task"></param>
/// <param name="cancellationToken"></param>
/// <see cref="https://blogs.msdn.microsoft.com/pfxteam/2012/10/05/how-do-i-cancel-non-cancelable-async-operations/"/>
/// <returns></returns>
public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using (cancellationToken.Register(x => ((TaskCompletionSource<bool>)x).TrySetResult(true), tcs))
{
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
}
return await task;
}
It is either verbatim copy pasted from a microsoft blog post or derivative of it
Upvotes: 1