-
Notifications
You must be signed in to change notification settings - Fork 847
Description
I'm running into an issue where some pre-existing code is no longer functioning as expected after updating to any version of FSharp.Core >= 5.0.2. The project is referencing a f# library that uses async from a C# mvc web project running .net framework 4.8. I'm noticing that Async.RunSynchronously just hangs and never returns when called from the web project. I was able to create a simple test project to reproduce the issue. The visual studio solution contains 3 projects; a f# library, C# console, and C# MVC project. All projects are .net framework 4.8. The same test function below works from the C# console project but not the C# MVC web project. It does work in the web project using FSharp.Core <=5.0.1 but all versions after don't seem to work.
namespace ReproduceAsyncError
module TestWork =
let test_parser x =
match System.Decimal.TryParse(x) with
| (true, d) -> Ok(d)
| _ -> Error(sprintf "'%s' is not a number" x)
let async_work x = async { return test_parser (x) }
let task_work = fun x -> task { return test_parser (x) }
let async_task_work x =
async {
let! t = task_work (x) |> Async.AwaitTask
return t
}
//hangs
let do_something_in_parallel () =
let x =
[ for i in 1 .. 50 -> i.ToString() ]
@ [ "Not A Number" ]
@ [ for i in 100 .. 150 -> i.ToString() ]
let transactions =
x
|> List.map (fun x -> (async_work x))
|> Async.Parallel
|> Async.RunSynchronously
transactions
//hangs
let do_something_in_parallel_with_async_tasks () =
let x =
[ for i in 1 .. 50 -> i.ToString() ]
@ [ "Not A Number" ]
@ [ for i in 100 .. 150 -> i.ToString() ]
let transactions =
x
|> List.map (fun x -> (async_task_work x))
|> Async.Parallel
|> Async.RunSynchronously
transactions
//hangs
let do_something_sequential () =
let x =
[ for i in 1 .. 50 -> i.ToString() ]
@ [ "Not A Number" ]
@ [ for i in 100 .. 150 -> i.ToString() ]
let transactions =
x
|> List.map (fun x -> (async_work x))
|> Async.Sequential
|> Async.RunSynchronously
transactions
//working
let do_single_async () =
let transactions = async_work "1" |> Async.RunSynchronously
transactions
//working
let do_something_in_parallel_with_tasks () =
let x = [ for i in 1 .. 50 -> i.ToString() ]
let transactions =
x
|> Array.ofList
|> Array.Parallel.map (fun p -> task_work(p).Result)
transactions
using System.Web.Mvc;
namespace TestWebApplication.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var p = ReproduceAsyncError.TestWork.do_something_in_parallel();
//var p = ReproduceAsyncError.TestWork.do_single_async();
//var p = ReproduceAsyncError.TestWork.do_something_in_parallel_with_async_tasks();
//var p = ReproduceAsyncError.TestWork.do_something_sequential();
//var p = ReproduceAsyncError.TestWork.do_something_in_parallel_with_tasks();
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}