Skip to content

Commit 37646b4

Browse files
committed
[core] Take advantage of IThreadPoolWorkItem
This can be used to provide an allocation-free way to enqueue tasks in the threadpool.
1 parent d0ce28b commit 37646b4

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
5+
namespace ReusableTasks
6+
{
7+
#if NET5_0_OR_GREATER || NETCOREAPP3_0_OR_GREATER
8+
class ActionWorkItem : IThreadPoolWorkItem
9+
{
10+
static readonly Action EmptyAction = () => { };
11+
static readonly Stack<ActionWorkItem> Cache = new Stack<ActionWorkItem>();
12+
13+
public Action Continuation { get; private set; } = EmptyAction;
14+
15+
public static ActionWorkItem GetOrCreate(Action action)
16+
{
17+
lock (Cache)
18+
{
19+
if (Cache.Count == 0)
20+
{
21+
return new ActionWorkItem { Continuation = action };
22+
}
23+
else
24+
{
25+
var worker = Cache.Pop();
26+
worker.Continuation = action;
27+
return worker;
28+
}
29+
}
30+
}
31+
32+
public void Execute()
33+
{
34+
var continuation = Continuation;
35+
Continuation = EmptyAction;
36+
37+
lock (Cache)
38+
Cache.Push(this);
39+
continuation();
40+
}
41+
}
42+
#endif
43+
}

src/ReusableTasks/ReusableTasks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project Sdk="Microsoft.NET.Sdk">
33

44
<PropertyGroup>
5-
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
5+
<TargetFrameworks>netstandard2.0;netstandard2.1;net5.0;netcoreapp3.0</TargetFrameworks>
66

77
<GenerateDocumentationFile>true</GenerateDocumentationFile>
88

src/ReusableTasks/System.Runtime.CompilerServices/ResultHolder_T.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,11 @@ void TryInvoke (Action callback)
205205
else if (SyncContext != null)
206206
SyncContext.Post (InvokeOnContext, callback);
207207
else
208+
#if NET5_0_OR_GREATER || NETCOREAPP3_0_OR_GREATER
209+
ThreadPool.UnsafeQueueUserWorkItem (ActionWorkItem.GetOrCreate (callback), false);
210+
#else
208211
ThreadPool.UnsafeQueueUserWorkItem (InvokeOnThreadPool, callback);
212+
#endif
209213
}
210214
}
211215
}

0 commit comments

Comments
 (0)