Fsharp: Async computation hanging in lastest F# 4.1 builds

Created on 24 Jun 2017  路  16Comments  路  Source: dotnet/fsharp

While going through the discussion in #3219 I noticed that a particular computation seems to be hanging when run in F# Interactive 4.1

cc @matthid

Repro steps

In F# Interactive 4.1

open System
open System.Threading
open System.Threading.Tasks

let test() =
    let tcs = new TaskCompletionSource<int>()
    let cts = new CancellationTokenSource()
    let _ = cts.Token.Register(fun () -> tcs.SetResult 42)
    async {
        cts.CancelAfter 500
        let! result = tcs.Task |> Async.AwaitTask
        return result
    } |> fun a -> Async.RunSynchronously(a, cancellationToken = cts.Token)

function test does execute as expected.

Expected behavior

Should fail with OperationCanceledException

Actual behavior

Hangs indefinitely

Workarounds

In compiled code, use FSharp.Core nuget package 4.1.17 (containing a version of FSharp.Core.dll 4.4.1.0 that does not contain this problem). Avoid using FSharp.Core nuget package 4.2.1 (which contains this problem).

In F# Interactive code, use a latest update to F# Interactive and your compiler tools (e.g.Visual Studio 2017 Update 3)

Related information

This only occurs in F# interactive 4.1 (32bit and 64bit builds) in both windows and mono/linux. It does not happen in console applications running FSharp.Core 4.4.1.0. I can't reproduce the issue in F# Interactive 4.0.

Area-Library Ready Severity-High bug regression

All 16 comments

@eiriktsarpalis If you want I can take care of this as well, as I'm already looking at the code and writing some tests. Even if we don't want to accept my PR as a whole we can probably cherry-pick this fix afterwards (or I can send a separate PR after the discussion)...

Hm I can't actually reproduce this. I have Microsoft (R) F# Interactive version 4.1 with

> typeof<option<_>>.Assembly.FullName;;
val it : string =
  "FSharp.Core, Version=4.4.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
> test();;
System.OperationCanceledException: The operation was canceled.
   at Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](AsyncImplResult`1 res)
   at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronouslyInAnotherThread[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
   at Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken token, FSharpAsync`1 computation, FSharpOption`1 timeout)
   at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
   at <StartupCode$FSI_0040>.$FSI_0040.main@()
Stopped due to error

Should fsi use another FSharp.Core version?

@matthid as a general rule in this project: please split things up in very very small parts. That increases the chances to get something in in time. Bug pull requests often rot for very long time since people are afraid to merge.

@forki Yeah I know, it's just for discussion and POC once we decide what is acceptable and what not I can split it up. Because this might mean doing things differently...

@matthid, @eiriktsarpalis I can reproduce this with the latest master starting fsi any cpu in debug mode.
It's waiting for a result... no end

@eiriktsarpalis I can now reproduce in a unit test :)

Weird, but it looks like I cannot reproduce when I launch fsi from the command line, only from Visual Studio. I can't reproduce in ionide on windows, but I it happens consistently in ionide on mono. Strange...

@eiriktsarpalis We need a version dif because it looks like this bug was introduced after the last update for the fsi on windows.

@realvictorprm Does VF# run a different build of fsi 4.1 than the one installed in the dev tools? Running

System.Reflection.Assembly.GetEntryAssembly().Location

seems to indicate that VF# launches some temp copy

C:\Users\eirik\AppData\Local\assembly\dl3\OW481XT9.V2P\5H7WMBY5.CXB\89e45b56\fa90b7d2_1becd201\fsiAnyCpu.exe (SHA abf85160c0cfbe880497a9990ee0748e3c14f64a)

whereas cli and ionide give the expected path

C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\FsiAnyCpu.exe (SHA cbb55cae8752ea1525ec4aa0165e5ee51850f6c9)

@realvictorprm My linux box uses the latest fsharp OSS built from source, which seems consistent with a recent bug causing this.

@eiriktsarpalis With the Visual F# solution you will always use the latest (nightly) version.
However if you're installing the Visual F# tools you're going to use the installed sdk stuff (so far I know).

@realvictorprm confirming that this reproduces with the latest master in F# OSS (commit 4f50d4f22e090a59889412f96fdefa0cc209a1c9). There's no version number as such printed in fsi other than the obvious (4.1)

@eiriktsarpalis I realized so too 馃槩 Currently trying to figure out the version of fsi on my pc. I do know that the last change to the file has been made on 10th May 馃槃

@eiriktsarpalis Problem is probably here: https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/FSharp.Core/control.fs#L1560

What the cancellationToken does at this place is cancel the Task which is RETURNED by ContinueWith which means the continuation is never called. I'd remove this parameter.

Bug was introduced here: https://github.com/Microsoft/visualfsharp/commit/7dfa68941ce9f6ccfe99575012943eaf95d46c0f

Btw it's a bit strange to call different overloads of ContinueWith depending on compiler directives. The helper function continueWithExtra even has different signatures as far as I can see...

Fixed - a huge thank you to both of you @matthid and @eiriktsarpalis

Was this page helpful?
0 / 5 - 0 ratings