PooledDelegate.cs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. namespace Cysharp.Threading.Tasks.Internal
  4. {
  5. internal sealed class PooledDelegate<T> : ITaskPoolNode<PooledDelegate<T>>
  6. {
  7. static TaskPool<PooledDelegate<T>> pool;
  8. PooledDelegate<T> nextNode;
  9. public ref PooledDelegate<T> NextNode => ref nextNode;
  10. static PooledDelegate()
  11. {
  12. TaskPool.RegisterSizeGetter(typeof(PooledDelegate<T>), () => pool.Size);
  13. }
  14. readonly Action<T> runDelegate;
  15. Action continuation;
  16. PooledDelegate()
  17. {
  18. runDelegate = Run;
  19. }
  20. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  21. public static Action<T> Create(Action continuation)
  22. {
  23. if (!pool.TryPop(out var item))
  24. {
  25. item = new PooledDelegate<T>();
  26. }
  27. item.continuation = continuation;
  28. return item.runDelegate;
  29. }
  30. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  31. void Run(T _)
  32. {
  33. var call = continuation;
  34. continuation = null;
  35. if (call != null)
  36. {
  37. pool.TryPush(this);
  38. call.Invoke();
  39. }
  40. }
  41. }
  42. }