-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch WorkPool of ConsumerWorkService to channels #882
Switch WorkPool of ConsumerWorkService to channels #882
Conversation
Looks good to me :) |
} | ||
|
||
static async Task OffloadToWorkerThreadPool(Action action, SemaphoreSlim limiter) | ||
{ | ||
try | ||
{ | ||
await Task.Run(() => action()); | ||
// like Task.Run but doesn't closure allocate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 I like =)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, it still allocates delegate. IIRC it is well known issue of Roslyn. If you really do not want allocate delegate each call then define static delegate and use it here.
dotnet/roslyn#39869
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sungam3r thanks for chiming in. You are welcome to submit a PR that changes the comment (and links to the Roslyn issue) or even switched to use a static delegate if it's a safe thing to do in this context. Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparison according to sharplab
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Action<object> <>9__0_0;
internal void <TaskFactory>b__0_0(object state)
{
((Action)state)();
}
}
awaiter = Task.Factory.StartNew(<>c.<>9__0_0 ?? (<>c.<>9__0_0 = new Action<object>(<>c.<>9.<TaskFactory>b__0_0)), action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).GetAwaiter();
so the Action
allocation happens once and is then cached for further execution in a static Action field.
vs Task.Run(() => action())
<>c__DisplayClass1_0 <>c__DisplayClass1_ = new <>c__DisplayClass1_0();
<>c__DisplayClass1_.action = action;
awaiter = Task.Run(new Action(<>c__DisplayClass1_.<TaskRun>b__0)).GetAwaiter();
display class creation for every run plus action allocation for every run
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wrong. Such lambda usage is OK. I re-read the Roslyn issue and remembered details.
Thanks everyone! |
Switch WorkPool of ConsumerWorkService to channels (cherry picked from commit c9eb9f1)
Backported to |
Proposed Changes
Switches WorkPool of ConsumerWorkService to channels
As discussed with @stebet in conversation over here #866 (comment)
Types of Changes
What types of changes does your code introduce to this project?
Put an
x
in the boxes that applyChecklist
Put an
x
in the boxes that apply. You can also fill these out after creatingthe PR. If you're unsure about any of them, don't hesitate to ask on the
mailing list. We're here to help! This is simply a reminder of what we are
going to look for before merging your code.
CONTRIBUTING.md
documentFurther Comments