Incoherent behavior when using a task with a unit returning statement, between Release and Debug
Please provide a succinct description of the issue.
When executing inside a task, a function that raises an exception is not called if the resulting expression ends in a property that has a unit value.
Provide the steps required to reproduce the problem:
- Run the attached code in debug, see that it does raise the exception with
failwithusing :dotnet run --configuration Debug - Run the attached code in release, see that it does not raise the exception using :
dotnet run --configuration Release
printfn "Hello from F#"
type SomeOutputType() =
member x.End = ()
let someFunctionWithReturnType () =
failwith "This should be raised"
SomeOutputType()
let theTaskAtHand () =
task {
(someFunctionWithReturnType ()).End
}
theTaskAtHand().Wait()
Provide a description of the expected behavior.
In both debug and release, the program fails after the exception is raised
Provide a description of the actual behavior observed.
In release, the exception is essentially ignored and nothing happens. Program exits successfully
In debug, the exception is raised and the program fails
Provide a description of any known workarounds.
You can pretty easily change this by switching it to being a function like so : member x.End = ignore and calling said function.
Using ``member x.End() = ()` will not work
Doing so inside an async computation expression will result in the expected behavior with the original code
Provide any related information:
Operating system: Windows 10 NET Runtime kind : .NET 6.0.201
To add some context :
- this was discovered in some tests where we end a fluent assertion with an
.Endproperty that results in the value(). This isn't amazing code, but it does provide some level of clarity better than havingignore - for me (and from my understanding) the issue here is that we don't get the same behavior, especially since the compiler has removed a statement that could contain important processes. In my use case, it would skip assertions entirely.
This seems more like and edge case, but still offers plenty of surprise when it happens
It seems that this function is not even called.
state machine's MoveNext method from original code:

when that line is changed to someFunctionWithReturnType() |> ignore
