Task Pool moved from Internal

master
neuecc 2020-06-04 14:52:36 +09:00
parent a1444c0b39
commit f4294d3752
7 changed files with 223 additions and 51 deletions

View File

@ -1,23 +0,0 @@
#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER
using System;
namespace Cysharp.Threading.Tasks.Internal
{
internal static class FuncExtensions
{
// avoid lambda capture
internal static Action<T> AsFuncOfT<T>(this Action action)
{
return new Action<T>(action.Invoke);
}
static void Invoke<T>(this Action action, T unused)
{
action();
}
}
}
#endif

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4d5a9a3e1f0f069478969f752fde29a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -71,9 +71,19 @@ namespace Cysharp.Threading.Tasks
dirty = true; dirty = true;
if (!EditorEnableState.EnableTracking) return; if (!EditorEnableState.EnableTracking) return;
var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : ""; var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : "";
string typeName;
if (EditorEnableState.EnableStackTrace)
{
var sb = new StringBuilder(); var sb = new StringBuilder();
TypeBeautify(task.GetType(), sb); TypeBeautify(task.GetType(), sb);
tracking.TryAdd(task, (sb.ToString(), Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace)); typeName = sb.ToString();
}
else
{
typeName = task.GetType().Name;
}
tracking.TryAdd(task, (typeName, Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace));
#endif #endif
} }

View File

@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
namespace Cysharp.Threading.Tasks.Internal namespace Cysharp.Threading.Tasks
{ {
// internaly used but public, allow to user create custom operator with pooling. // internaly used but public, allow to user create custom operator with pooling.

View File

@ -1,6 +1,8 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using Cysharp.Threading.Tasks.Internal;
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
namespace Cysharp.Threading.Tasks namespace Cysharp.Threading.Tasks
@ -102,8 +104,7 @@ namespace Cysharp.Threading.Tasks
} }
/// <summary> /// <summary>
/// helper of create add UniTaskVoid to delegate. /// helper of fire and forget void action.
/// For example: FooEvent += () => UniTask.Void(async () => { /* */ })
/// </summary> /// </summary>
public static void Void(Func<UniTaskVoid> asyncAction) public static void Void(Func<UniTaskVoid> asyncAction)
{ {
@ -111,7 +112,7 @@ namespace Cysharp.Threading.Tasks
} }
/// <summary> /// <summary>
/// helper of create add UniTaskVoid to delegate. /// helper of fire and forget void action.
/// </summary> /// </summary>
public static void Void(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken) public static void Void(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
{ {
@ -119,8 +120,7 @@ namespace Cysharp.Threading.Tasks
} }
/// <summary> /// <summary>
/// helper of create add UniTaskVoid to delegate. /// helper of fire and forget void action.
/// For example: FooEvent += (sender, e) => UniTask.Void(async arg => { /* */ }, (sender, e))
/// </summary> /// </summary>
public static void Void<T>(Func<T, UniTaskVoid> asyncAction, T state) public static void Void<T>(Func<T, UniTaskVoid> asyncAction, T state)
{ {
@ -133,7 +133,7 @@ namespace Cysharp.Threading.Tasks
/// </summary> /// </summary>
public static Action Action(Func<UniTaskVoid> asyncAction) public static Action Action(Func<UniTaskVoid> asyncAction)
{ {
return () => asyncAction().Forget(); return AsyncAction.Create(asyncAction);
} }
/// <summary> /// <summary>
@ -141,7 +141,7 @@ namespace Cysharp.Threading.Tasks
/// </summary> /// </summary>
public static Action Action(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken) public static Action Action(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
{ {
return () => asyncAction(cancellationToken).Forget(); return AsyncActionWithCancellation.Create(asyncAction, cancellationToken);
} }
#if UNITY_2018_3_OR_NEWER #if UNITY_2018_3_OR_NEWER
@ -152,7 +152,7 @@ namespace Cysharp.Threading.Tasks
/// </summary> /// </summary>
public static UnityEngine.Events.UnityAction UnityAction(Func<UniTaskVoid> asyncAction) public static UnityEngine.Events.UnityAction UnityAction(Func<UniTaskVoid> asyncAction)
{ {
return () => asyncAction().Forget(); return AsyncUnityAction.Create(asyncAction);
} }
/// <summary> /// <summary>
@ -161,7 +161,7 @@ namespace Cysharp.Threading.Tasks
/// </summary> /// </summary>
public static UnityEngine.Events.UnityAction UnityAction(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken) public static UnityEngine.Events.UnityAction UnityAction(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
{ {
return () => asyncAction(cancellationToken).Forget(); return AsyncUnityActionWithCancellation.Create(asyncAction, cancellationToken);
} }
#endif #endif
@ -260,6 +260,194 @@ namespace Cysharp.Threading.Tasks
return task.Status; return task.Status;
} }
} }
sealed class AsyncAction : ITaskPoolNode<AsyncAction>
{
static TaskPool<AsyncAction> pool;
public AsyncAction NextNode { get; set; }
static AsyncAction()
{
TaskPool.RegisterSizeGetter(typeof(AsyncAction), () => pool.Size);
}
readonly Action runDelegate;
Func<UniTaskVoid> voidAction;
AsyncAction()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Action Create(Func<UniTaskVoid> voidAction)
{
if (!pool.TryPop(out var item))
{
item = new AsyncAction();
}
item.voidAction = voidAction;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
var call = voidAction;
voidAction = null;
if (call != null)
{
pool.TryPush(this);
call.Invoke();
}
}
}
sealed class AsyncActionWithCancellation : ITaskPoolNode<AsyncActionWithCancellation>
{
static TaskPool<AsyncActionWithCancellation> pool;
public AsyncActionWithCancellation NextNode { get; set; }
static AsyncActionWithCancellation()
{
TaskPool.RegisterSizeGetter(typeof(AsyncActionWithCancellation), () => pool.Size);
}
readonly Action runDelegate;
CancellationToken cancellationToken;
Func<CancellationToken, UniTaskVoid> voidAction;
AsyncActionWithCancellation()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Action Create(Func<CancellationToken, UniTaskVoid> voidAction, CancellationToken cancellationToken)
{
if (!pool.TryPop(out var item))
{
item = new AsyncActionWithCancellation();
}
item.voidAction = voidAction;
item.cancellationToken = cancellationToken;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
var call = voidAction;
var ct = cancellationToken;
voidAction = null;
cancellationToken = default;
if (call != null)
{
pool.TryPush(this);
call.Invoke(ct);
}
}
}
#if UNITY_2018_3_OR_NEWER
sealed class AsyncUnityAction : ITaskPoolNode<AsyncUnityAction>
{
static TaskPool<AsyncUnityAction> pool;
public AsyncUnityAction NextNode { get; set; }
static AsyncUnityAction()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUnityAction), () => pool.Size);
}
readonly UnityEngine.Events.UnityAction runDelegate;
Func<UniTaskVoid> voidAction;
AsyncUnityAction()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static UnityEngine.Events.UnityAction Create(Func<UniTaskVoid> voidAction)
{
if (!pool.TryPop(out var item))
{
item = new AsyncUnityAction();
}
item.voidAction = voidAction;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
var call = voidAction;
voidAction = null;
if (call != null)
{
pool.TryPush(this);
call.Invoke();
}
}
}
sealed class AsyncUnityActionWithCancellation : ITaskPoolNode<AsyncUnityActionWithCancellation>
{
static TaskPool<AsyncUnityActionWithCancellation> pool;
public AsyncUnityActionWithCancellation NextNode { get; set; }
static AsyncUnityActionWithCancellation()
{
TaskPool.RegisterSizeGetter(typeof(AsyncUnityActionWithCancellation), () => pool.Size);
}
readonly UnityEngine.Events.UnityAction runDelegate;
CancellationToken cancellationToken;
Func<CancellationToken, UniTaskVoid> voidAction;
AsyncUnityActionWithCancellation()
{
runDelegate = Run;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static UnityEngine.Events.UnityAction Create(Func<CancellationToken, UniTaskVoid> voidAction, CancellationToken cancellationToken)
{
if (!pool.TryPop(out var item))
{
item = new AsyncUnityActionWithCancellation();
}
item.voidAction = voidAction;
item.cancellationToken = cancellationToken;
return item.runDelegate;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Run()
{
var call = voidAction;
var ct = cancellationToken;
voidAction = null;
cancellationToken = default;
if (call != null)
{
pool.TryPush(this);
call.Invoke(ct);
}
}
}
#endif
} }
internal static class CompletedTasks internal static class CompletedTasks

View File

@ -295,6 +295,12 @@ public class SandboxMain : MonoBehaviour
return req; return req;
} }
async Task<int> Test()
{
await Task.Yield();
return 10;
}
async UniTaskVoid Start() async UniTaskVoid Start()
{ {
@ -323,13 +329,15 @@ public class SandboxMain : MonoBehaviour
//await okButton.GetComponent<RectTransform>().DOMoveY(10.2f, 3).WithCancellation(CancellationToken.None); //await okButton.GetComponent<RectTransform>().DOMoveY(10.2f, 3).WithCancellation(CancellationToken.None);
//Debug.Log("AGAIN END MOVE"); //Debug.Log("AGAIN END MOVE");
Debug.Log(Test().GetType().FullName);
// check stacktrace // check stacktrace
await UniTaskAsyncEnumerable.EveryUpdate().Where((x, i) => i % 2 == 0).Select(x => x).DistinctUntilChanged().ForEachAsync(x => // await UniTaskAsyncEnumerable.EveryUpdate().Where((x, i) => i % 2 == 0).Select(x => x).DistinctUntilChanged().ForEachAsync(x =>
{ //{
Debug.Log("test"); // Debug.Log("test");
}); //});