#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Collections;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using UniRx.Async.Internal;
namespace UniRx.Async
{
public static partial class UniTaskExtensions
{
///
/// Convert Task[T] -> UniTask[T].
///
public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
{
var promise = new UniTaskCompletionSource();
task.ContinueWith((x, state) =>
{
var p = (UniTaskCompletionSource)state;
switch (x.Status)
{
case TaskStatus.Canceled:
p.TrySetCanceled();
break;
case TaskStatus.Faulted:
p.TrySetException(x.Exception);
break;
case TaskStatus.RanToCompletion:
p.TrySetResult(x.Result);
break;
default:
throw new NotSupportedException();
}
}, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current);
return promise.Task;
}
///
/// Convert Task -> UniTask.
///
public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
{
var promise = new UniTaskCompletionSource();
task.ContinueWith((x, state) =>
{
var p = (UniTaskCompletionSource)state;
switch (x.Status)
{
case TaskStatus.Canceled:
p.TrySetCanceled();
break;
case TaskStatus.Faulted:
p.TrySetException(x.Exception);
break;
case TaskStatus.RanToCompletion:
p.TrySetResult();
break;
default:
throw new NotSupportedException();
}
}, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current);
return promise.Task;
}
public static Task AsTask(this UniTask task)
{
try
{
UniTask.Awaiter awaiter;
try
{
awaiter = task.GetAwaiter();
}
catch (Exception ex)
{
return Task.FromException(ex);
}
if (awaiter.IsCompleted)
{
try
{
var result = awaiter.GetResult();
return Task.FromResult(result);
}
catch (Exception ex)
{
return Task.FromException(ex);
}
}
var tcs = new TaskCompletionSource();
awaiter.SourceOnCompleted(state =>
{
using (var tuple = (StateTuple, UniTask.Awaiter>)state)
{
var (inTcs, inAwaiter) = tuple;
try
{
var result = inAwaiter.GetResult();
inTcs.SetResult(result);
}
catch (Exception ex)
{
inTcs.SetException(ex);
}
}
}, StateTuple.Create(tcs, awaiter));
return tcs.Task;
}
catch (Exception ex)
{
return Task.FromException(ex);
}
}
public static Task AsTask(this UniTask task)
{
try
{
UniTask.Awaiter awaiter;
try
{
awaiter = task.GetAwaiter();
}
catch (Exception ex)
{
return Task.FromException(ex);
}
if (awaiter.IsCompleted)
{
try
{
awaiter.GetResult(); // check token valid on Succeeded
return Task.CompletedTask;
}
catch (Exception ex)
{
return Task.FromException(ex);
}
}
var tcs = new TaskCompletionSource