Skip to content
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

VSTHRD103 is produced inside of ContinueWith when passing task.Result as an argument for async function. #1125

Open
MaximTrushin opened this issue Dec 9, 2022 · 5 comments

Comments

@MaximTrushin
Copy link

MaximTrushin commented Dec 9, 2022

VS 2022 v17.4.2:

Steps to Reproduce:

Try to compile the following code:

...

Task<Expr.Nullable<int>> r1 = TestAsyncDelayAsync(15).ContinueWith((Task<Expr.Nullable<int>> task) => {
	return TestAsyncDelayAsync(task.**Result**.Value + 10);
}, TaskScheduler.Default).Unwrap();

var r2 = TestAsyncDelayAsync(15).ContinueWith((Task<Expr.Nullable<int>> task) => {
				return TestDelay(task.Result.Value + 10);
			}, TaskScheduler.Default);
...
...

public async Task<Expr.Nullable<int>> TestAsyncDelayAsync(int delayMilliseconds) {
	await Task.Delay(TimeSpan.FromMilliseconds(delayMilliseconds));
	return new Expr.Nullable<int>(delayMilliseconds);
}

public Expr.Nullable<int> TestDelay(int delayMilliseconds) {
	return new Expr.Nullable<int>(delayMilliseconds);
}

The assignment to r1 produces the VSTHRD103, but the assignment to r2 doesn't.

Expected Behavior:
The warning must not be produced because the task is always completed when the lambda defined in ContinueWith is called.

Actual Behavior:
VSTHRD103 is produced inside of ContinueWith when passing task.Result as an argument for async function.

@AArnott
Copy link
Member

AArnott commented Jan 6, 2023

tip, @MaximTrushin: use 3 backticks in a row around your multi-line code snippets so github formats them properly. Adding a cs after the opening 3 backticks adds syntax colorization.

@AArnott
Copy link
Member

AArnott commented Jan 6, 2023

Can you include the actual emitted warning? I'm surprised that VSTHRD103 is doing this because I thought that was the job of VSTHRD002.
In any case though, there are several ContinueWith scenarios. This one seems similar to #1123.

@MaximTrushin
Copy link
Author

This is the emitted warning:

[VSTHRD103] Result synchronously blocks. Use await instead.

For some reason, I can't reproduce the issue when using a small console application or library assembly. I see it happening only in bigger projects.

@manfred-brands
Copy link

manfred-brands commented Sep 13, 2024

I still see this in version 17.11.20 and can repeat it with a small class:

namespace VSTHRD103;

public sealed class VSTHRD103
{
    public static Task<Thing> CreateAsync() => Task.FromResult(new Thing());

    public static Task<Thing> CreateWithNameAsync() => CreateAsync().ContinueWith(t => t.Result.EnsureNameAsync("Name"), TaskScheduler.Default).Unwrap();
}

public sealed class Thing
{
    public string? Name { get; private set; }

    public Task<Thing> EnsureNameAsync(string name)
    {
        Name = name;
        return Task.FromResult(this);
    }
}

image

@manfred-brands
Copy link

Your unit test with a ContinueWith: task.ContinueWith(t => { Console.WriteLine(t.Result); });
bails out because the method is an Action not a Func returning Task.

I don't see any code in the actual Analyzer making exemptions when called from inside a ContinueWith

@AArnott AArnott added the bug label Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants