mirror of https://github.com/Cysharp/UniTask
use PooledDelegate to avoid convert Action to Action<AsyncOperation> allocation
parent
35b933730b
commit
10fb8060fa
|
@ -59,7 +59,7 @@ namespace Cysharp.Threading.Tasks
|
|||
|
||||
#if NETCOREAPP3_1
|
||||
|
||||
public sealed class ThreadPoolWorkItem : IThreadPoolWorkItem
|
||||
sealed class ThreadPoolWorkItem : IThreadPoolWorkItem
|
||||
{
|
||||
static readonly ConcurrentQueue<ThreadPoolWorkItem> pool = new ConcurrentQueue<ThreadPoolWorkItem>();
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
|
||||
handle.Completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
|
||||
handle.CompletedTypeless += continuationAction;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
using Cysharp.Threading.Tasks.Internal;
|
||||
using DG.Tweening;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
|
@ -77,9 +78,8 @@ namespace Cysharp.Threading.Tasks
|
|||
|
||||
public void UnsafeOnCompleted(System.Action continuation)
|
||||
{
|
||||
// convert Action -> TweenCallback allocation.
|
||||
// onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true).
|
||||
tween.onKill = new TweenCallback(continuation);
|
||||
tween.onKill = PooledTweenCallback.Create(continuation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,8 @@ namespace Cysharp.Threading.Tasks
|
|||
static readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
|
||||
static readonly TweenCallback EmptyTweenCallback = () => { };
|
||||
|
||||
readonly TweenCallback onKillDelegate;
|
||||
|
||||
Tween tween;
|
||||
TweenCancelBehaviour cancelBehaviour;
|
||||
CancellationToken cancellationToken;
|
||||
|
@ -99,7 +101,7 @@ namespace Cysharp.Threading.Tasks
|
|||
|
||||
TweenConfiguredSource()
|
||||
{
|
||||
|
||||
onKillDelegate = OnKill;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, out short token)
|
||||
|
@ -130,8 +132,7 @@ namespace Cysharp.Threading.Tasks
|
|||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
|
||||
}
|
||||
|
||||
// allocate delegate.
|
||||
tween.OnKill(new TweenCallback(OnKill));
|
||||
tween.OnKill(onKillDelegate);
|
||||
}
|
||||
|
||||
void OnKill()
|
||||
|
@ -234,6 +235,45 @@ namespace Cysharp.Threading.Tasks
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PooledTweenCallback
|
||||
{
|
||||
static readonly ConcurrentQueue<PooledTweenCallback> pool = new ConcurrentQueue<PooledTweenCallback>();
|
||||
|
||||
readonly TweenCallback runDelegate;
|
||||
|
||||
Action continuation;
|
||||
|
||||
|
||||
PooledTweenCallback()
|
||||
{
|
||||
runDelegate = Run;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TweenCallback Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryDequeue(out var item))
|
||||
{
|
||||
item = new PooledTweenCallback();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item.runDelegate;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Run()
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
if (call != null)
|
||||
{
|
||||
pool.Enqueue(this);
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
internal class PooledDelegate<T>
|
||||
{
|
||||
static readonly ConcurrentQueue<PooledDelegate<T>> pool = new ConcurrentQueue<PooledDelegate<T>>();
|
||||
|
||||
readonly Action<T> runDelegate;
|
||||
|
||||
Action continuation;
|
||||
|
||||
|
||||
PooledDelegate()
|
||||
{
|
||||
runDelegate = Run;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Action<T> Create(Action continuation)
|
||||
{
|
||||
if (!pool.TryDequeue(out var item))
|
||||
{
|
||||
item = new PooledDelegate<T>();
|
||||
}
|
||||
|
||||
item.continuation = continuation;
|
||||
return item.runDelegate;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Run(T _)
|
||||
{
|
||||
var call = continuation;
|
||||
continuation = null;
|
||||
if (call != null)
|
||||
{
|
||||
pool.Enqueue(this);
|
||||
call.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8932579438742fa40b010edd412dbfba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -14,36 +14,6 @@ namespace Cysharp.Threading.Tasks
|
|||
public void Forget()
|
||||
{
|
||||
}
|
||||
|
||||
// [DebuggerHidden]
|
||||
// public Awaiter GetAwaiter()
|
||||
// {
|
||||
// return new Awaiter();
|
||||
// }
|
||||
|
||||
// public struct Awaiter : ICriticalNotifyCompletion
|
||||
// {
|
||||
// [DebuggerHidden]
|
||||
// public bool IsCompleted => true;
|
||||
|
||||
// [DebuggerHidden]
|
||||
// public void GetResult()
|
||||
// {
|
||||
//#if UNITY_2018_3_OR_NEWER
|
||||
// UnityEngine.Debug.LogWarning("UniTaskVoid can't await, always fire-and-forget. use Forget instead of await.");
|
||||
//#endif
|
||||
// }
|
||||
|
||||
// [DebuggerHidden]
|
||||
// public void OnCompleted(Action continuation)
|
||||
// {
|
||||
// }
|
||||
|
||||
// [DebuggerHidden]
|
||||
// public void UnsafeOnCompleted(Action continuation)
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
@ -774,7 +774,7 @@ namespace Cysharp.Threading.Tasks
|
|||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ using UnityEngine;
|
|||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
// using DG.Tweening;
|
||||
|
||||
public struct MyJob : IJob
|
||||
|
@ -259,11 +258,15 @@ public class SandboxMain : MonoBehaviour
|
|||
{
|
||||
try
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
var r = UniAsync("https://bing.com/", cts.Token);
|
||||
cts.Cancel();
|
||||
await r;
|
||||
Debug.Log("UNIASYNC");
|
||||
//var cts = new CancellationTokenSource();
|
||||
//var r = UniAsync("https://bing.com/", cts.Token);
|
||||
//cts.Cancel();
|
||||
//await r;
|
||||
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||
Debug.Log("UNIASYNC1 ");
|
||||
|
||||
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||
Debug.Log("UNIASYNC2");
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -291,7 +294,7 @@ public class SandboxMain : MonoBehaviour
|
|||
}
|
||||
|
||||
|
||||
void Start()
|
||||
async UniTaskVoid Start()
|
||||
{
|
||||
//UniTaskAsyncEnumerable.EveryValueChanged(mcc, x => x.MyProperty)
|
||||
// .Do(_ => { }, () => Debug.Log("COMPLETED"))
|
||||
|
@ -301,15 +304,23 @@ public class SandboxMain : MonoBehaviour
|
|||
// })
|
||||
// .Forget();
|
||||
|
||||
_ = Test1();
|
||||
//_ = Test1();
|
||||
Test2().Forget();
|
||||
StartCoroutine(Test3("https://bing.com/"));
|
||||
//StartCoroutine(Test3("https://bing.com/"));
|
||||
|
||||
|
||||
// DG.Tweening.Core.TweenerCore<int>
|
||||
//okButton.GetComponent<RectTransform>().DOMoveX(10.2f, 30);
|
||||
//Debug.Log("GO MOVEX");
|
||||
//await okButton.GetComponent<RectTransform>().DOMoveX(-10.2f, 3).WithCancellation(CancellationToken.None);
|
||||
//Debug.Log("END MOVEX");
|
||||
|
||||
|
||||
//Debug.Log("AGAIN MOVE");
|
||||
//await okButton.GetComponent<RectTransform>().DOMoveY(10.2f, 3).WithCancellation(CancellationToken.None);
|
||||
//Debug.Log("AGAIN END MOVE");
|
||||
|
||||
|
||||
await UniTask.Yield();
|
||||
// DOTween.To(
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
|
|
Loading…
Reference in New Issue