Use AsyncOperation.completed callback usually

master
hadashiA 2023-11-02 12:01:51 +09:00
parent 39cf81d2ab
commit 0579984355
2 changed files with 104 additions and 92 deletions

View File

@ -26,17 +26,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static UniTask WithCancellation(this AsyncOperation asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
if (asyncOperation.isDone) return UniTask.CompletedTask; if (asyncOperation.isDone) return UniTask.CompletedTask;
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct AsyncOperationAwaiter : ICriticalNotifyCompletion public struct AsyncOperationAwaiter : ICriticalNotifyCompletion
@ -105,7 +105,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -121,19 +121,16 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (AsyncOperationConfiguredSource)state;
{ source.core.TrySetCanceled(source.cancellationToken);
var source = (AsyncOperationConfiguredSource)state; }, result);
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -180,6 +177,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);
@ -242,17 +244,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static UniTask<UnityEngine.Object> WithCancellation(this ResourceRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static UniTask<UnityEngine.Object> WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct ResourceRequestAwaiter : ICriticalNotifyCompletion public struct ResourceRequestAwaiter : ICriticalNotifyCompletion
@ -325,7 +327,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -341,19 +343,16 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (ResourceRequestConfiguredSource)state;
{ source.core.TrySetCanceled(source.cancellationToken);
var source = (ResourceRequestConfiguredSource)state; }, result);
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -404,6 +403,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);
@ -467,17 +471,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static UniTask<UnityEngine.Object> WithCancellation(this AssetBundleRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static UniTask<UnityEngine.Object> WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion
@ -550,7 +554,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -566,19 +570,16 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (AssetBundleRequestConfiguredSource)state;
{ source.core.TrySetCanceled(source.cancellationToken);
var source = (AssetBundleRequestConfiguredSource)state; }, result);
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -629,6 +630,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);
@ -693,17 +699,17 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static UniTask<AssetBundle> WithCancellation(this AssetBundleCreateRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static UniTask<AssetBundle> WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<AssetBundle>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<AssetBundle>(cancellationToken);
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle);
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion
@ -776,7 +782,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -792,19 +798,16 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (AssetBundleCreateRequestConfiguredSource)state;
{ source.core.TrySetCanceled(source.cancellationToken);
var source = (AssetBundleCreateRequestConfiguredSource)state; }, result);
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -855,6 +858,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);
@ -919,12 +927,12 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static UniTask<UnityWebRequest> WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static UniTask<UnityWebRequest> WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityWebRequest>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityWebRequest>(cancellationToken);
@ -936,7 +944,7 @@ namespace Cysharp.Threading.Tasks
} }
return UniTask.FromResult(asyncOperation.webRequest); return UniTask.FromResult(asyncOperation.webRequest);
} }
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion
@ -1017,7 +1025,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -1033,20 +1041,17 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (UnityWebRequestAsyncOperationConfiguredSource)state;
{ source.asyncOperation.webRequest.Abort();
var source = (UnityWebRequestAsyncOperationConfiguredSource)state; source.core.TrySetCanceled(source.cancellationToken);
source.asyncOperation.webRequest.Abort(); }, result);
source.core.TrySetCanceled(source.cancellationToken);
}, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -1098,6 +1103,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);

View File

@ -54,12 +54,12 @@ namespace Cysharp.Threading.Tasks
return ToUniTask(asyncOperation, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
} }
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, bool handleImmediately, CancellationToken cancellationToken) public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
{ {
return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
} }
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
{ {
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<#= IsVoid(t) ? "" : "<" + t.returnType + ">" #>(cancellationToken); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<#= IsVoid(t) ? "" : "<" + t.returnType + ">" #>(cancellationToken);
@ -75,7 +75,7 @@ namespace Cysharp.Threading.Tasks
<# } else { #> <# } else { #>
if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>; if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>;
<# } #> <# } #>
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
} }
public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion
@ -168,7 +168,7 @@ namespace Cysharp.Threading.Tasks
continuationAction = Continuation; continuationAction = Continuation;
} }
public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, bool handleImmediately, CancellationToken cancellationToken, out short token) public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
{ {
@ -184,22 +184,19 @@ namespace Cysharp.Threading.Tasks
result.progress = progress; result.progress = progress;
result.cancellationToken = cancellationToken; result.cancellationToken = cancellationToken;
result.completed = false; result.completed = false;
asyncOperation.completed += result.continuationAction;
if (handleImmediately) if (cancelImmediately && cancellationToken.CanBeCanceled)
{ {
asyncOperation.completed += result.continuationAction; result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
if (cancellationToken.CanBeCanceled)
{ {
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => var source = (<#= t.typeName #>ConfiguredSource)state;
{
var source = (<#= t.typeName #>ConfiguredSource)state;
<# if(IsUnityWebRequest(t)) { #> <# if(IsUnityWebRequest(t)) { #>
source.asyncOperation.webRequest.Abort(); source.asyncOperation.webRequest.Abort();
<# } #> <# } #>
source.core.TrySetCanceled(source.cancellationToken); source.core.TrySetCanceled(source.cancellationToken);
}, result); }, result);
}
} }
TaskTracker.TrackActiveTask(result, 3); TaskTracker.TrackActiveTask(result, 3);
@ -259,6 +256,11 @@ namespace Cysharp.Threading.Tasks
return false; return false;
} }
if (asyncOperation == null)
{
return false;
}
if (progress != null) if (progress != null)
{ {
progress.Report(asyncOperation.progress); progress.Report(asyncOperation.progress);