All Projects → kekyo → Fsharp.control.fusiontasks

kekyo / Fsharp.control.fusiontasks

Licence: other
F# Async workflow <--> .NET Task/ValueTask easy seamless interoperability library.

Programming Languages

csharp
926 projects
fsharp
127 projects

Projects that are alternatives of or similar to Fsharp.control.fusiontasks

Swimmer
🏊 Swimmer - An async task pooling and throttling utility for JS
Stars: ✭ 94 (-6.93%)
Mutual labels:  async, task
Laravel S
LaravelS is an out-of-the-box adapter between Swoole and Laravel/Lumen.
Stars: ✭ 3,479 (+3344.55%)
Mutual labels:  async, task
Asyncex
A helper library for async/await.
Stars: ✭ 2,794 (+2666.34%)
Mutual labels:  async, task
Unityfx.async
Asynchronous operations (promises) for Unity3d.
Stars: ✭ 143 (+41.58%)
Mutual labels:  async, task
Fennel
A task queue library for Python and Redis
Stars: ✭ 24 (-76.24%)
Mutual labels:  async, task
Taskbuilder.fs
F# computation expression builder for System.Threading.Tasks
Stars: ✭ 217 (+114.85%)
Mutual labels:  async, task
Tinytask
A Tiny Task Library
Stars: ✭ 315 (+211.88%)
Mutual labels:  async, task
Vue Concurrency
A library for encapsulating asynchronous operations and managing concurrency for Vue and Composition API.
Stars: ✭ 147 (+45.54%)
Mutual labels:  async, task
Then
🎬 Tame async code with battle-tested promises
Stars: ✭ 908 (+799.01%)
Mutual labels:  async, task
Asyncawaitbestpractices
Extensions for System.Threading.Tasks.Task and System.Threading.Tasks.ValueTask
Stars: ✭ 693 (+586.14%)
Mutual labels:  async, task
Task Easy
A simple, customizable, and lightweight priority queue for promises.
Stars: ✭ 244 (+141.58%)
Mutual labels:  async, task
Rq
Simple job queues for Python
Stars: ✭ 8,065 (+7885.15%)
Mutual labels:  async, task
Fun Task
Abstraction for managing asynchronous code in JS
Stars: ✭ 363 (+259.41%)
Mutual labels:  async, task
Taskmanager
A simple、 light(only two file)、fast 、powerful 、easy to use 、easy to extend 、 Android Library To Manager your AsyncTask/Thread/CallBack Jobqueue ! 一个超级简单,易用,轻量级,快速的异步任务管理器,类似于AsyncTask,但是比AsyncTask更好用,更易控制,从此不再写Thread ! ^_^
Stars: ✭ 25 (-75.25%)
Mutual labels:  async, task
Flowa
🔥Service level control flow for Node.js
Stars: ✭ 66 (-34.65%)
Mutual labels:  async, task
Dazzle
Next-Gen Async Library for PHP
Stars: ✭ 90 (-10.89%)
Mutual labels:  async
Meinheld
Meinheld is a high performance asynchronous WSGI Web Server (based on picoev)
Stars: ✭ 1,339 (+1225.74%)
Mutual labels:  async
Alecrimasynckit
async and await for Swift.
Stars: ✭ 89 (-11.88%)
Mutual labels:  async
Nginx Haskell Module
Nginx module for binding Haskell code in configuration files for great good!
Stars: ✭ 99 (-1.98%)
Mutual labels:  async
Object Observer
Object Observer functionality of JavaScript objects/arrays via native Proxy
Stars: ✭ 88 (-12.87%)
Mutual labels:  async

F# FusionTasks

FusionTasks

Status

main devel
NuGet Package (F# 5.0/4.5) NuGet FusionTasks
Continuous integration RelaxVersioner CI build (main) RelaxVersioner CI build (main)

What is this?

  • F# Async workflow <--> .NET Task/ValueTask easy seamless interoperability library.
  • Sample codes (F# side):
let asyncTest = async {
  use ms = new MemoryStream()

  // FusionTasks directly interpreted System.Threading.Tasks.Task class in F# async-workflow block.
  do! ms.WriteAsync(data, 0, data.Length)
  do ms.Position <- 0L

  // FusionTasks directly interpreted System.Threading.Tasks.Task<T> class in F# async-workflow block.
  let! length = ms.ReadAsync(data2, 0, data2.Length)
  do length |> should equal data2.Length
}
  • Sample codes (C# side):
using System.Threading.Tasks;
using Microsoft.FSharp.Control;

public async Task AsyncTest(FSharpAsync<int> asyncIntComp)
{
  // FusionTasks simple usage F#'s Async<unit> direct awaitable.
  await FSharpAsync.Sleep(500);
  Console.WriteLine("Awaited F# async function (unit).");

  // FusionTasks simple usage F#'s Async<int> direct awaitable.
  var result = await asyncIntComp;
  Console.WriteLine("Awaited F# async function: Result=" + result);
}

Features

  • Easy interoperability .NET Task/ValueTask <--> F#'s Async.
  • F# async workflow block now support direct .NET Task/ValueTask handle with let!, do! and use!.
  • .NET (C# async-await) now support directly F#'s Async.
  • SyncronizationContext capture operation support (F#: AsyncConfigure method / .NET (C#) AsAsyncConfigured method)

Benefits

  • Easy interoperability, combination and relation standard .NET OSS packages using Task/ValueTask and F#'s Async.
  • F# 5.0/4.5 with .NET 5, .NET Core 3.0/2.0 (or higher), .NET Standard 1.6/2.0 and .NET Framework 4.5/4.6.1/4.8.
  • Ready to LINQPad 5.

Environments

  • F# 5.0/4.5
  • .NET 5
  • .NET Core 3.0/2.0 or higher
  • .NET Standard 1.6/2.0/2.1
  • .NET Framework 4.5/4.6.1/4.8

How to use

  • Search NuGet package and install "FSharp.Control.FusionTasks".
  • F# use, autoopen'd namespace "FSharp.Control". "System.Threading.Tasks" is optional.
  • C# use, using namespace "System.Threading.Tasks". "Microsoft.FSharp.Control" is optional.

Samples

Basic async workflow:

let asyncTest = async {
  use ms = new MemoryStream()

  // FusionTasks directly interpreted System.Threading.Tasks.Task class in F# async-workflow block.
  // Sure, non-generic Task mapping to Async<unit>.
  do! ms.WriteAsync(data, 0, data.Length)
  do ms.Position <- 0L

  // FusionTasks directly interpreted System.Threading.Tasks.Task<T> class in F# async-workflow block.
  // Standard usage, same as manually used Async.AwaitTask.
  let! length = ms.ReadAsync(data2, 0, data2.Length)
  do length |> should equal data2.Length
}

Without async workflow:

use ms = new MemoryStream()

// Manually conversion by "AsAsync" : Task<T> --> Async<'T>
let length = ms.ReadAsync(data, 0, data.Length).AsAsync() |> Async.RunSynchronosly

Without async workflow (CancellationToken):

use ms = new MemoryStream()
let cts = new CancellationTokenSource()

// Produce with CancellationToken:
// TIPS: FusionTasks cannot handle directly CancellationToken IN ASYNC WORKFLOW.
//   Because async workflow semantics implicitly handled CancellationToken with Async.DefaultCancellationToken, CancellationToken and CancelDefaultToken().
//   (CancellationToken derived from Async.StartWithContinuations() in async workflow.)
let length = ms.ReadAsync(data, 0, data.Length).AsAsync(cts.Token) |> Async.RunSynchronosly

Handle Task.ConfigureAwait(...) (Capture/release SynchContext):

let asyncTest = async {
  use ms = new MemoryStream()

  // Task<T> --> ConfiguredAsyncAwaitable<'T> :
  // Why use AsyncConfigure() instead ConfigureAwait() ?
  //   Because the "ConfiguredTaskAwaitable<T>" lack declare the TypeForwardedTo attribute in some PCL.
  //   If use AsyncConfigure(), complete hidden refer ConfiguredTaskAwaitable into FusionTasks assembly,
  //   avoid strange linking errors.
  let! length = ms.ReadAsync(data, 0, data.Length).AsyncConfigure(false)
}

Delegate async continuation - works like TaskCompletionSource<T>:

open System.Threading

let asyncCalculate() =
  // Create AsyncCompletionSource<'T>.
  let acs = new AsyncCompletionSource<int>()

  // Execution with completely independent another thread...
  let thread = new Thread(new ThreadStart(fun _ ->
    Thread.Sleep(5000)
    // If you captured thread context (normally continuation or callbacks),
    // can delegation async continuation using AsyncCompletionSource<'T>.
    acs.SetResult(123 * 456)))
  thread.Start()

  // Async<'T> instance
  acs.Async

TIPS: We have to add annotation for arguments if using it async workflow:

let asyncInner arg0 = async {
  // Cause FS0041:
  //   A unique overload for method 'Source' could not be determined based on type information prior to this program point.
  //   A type annotation may be needed.
  //  --> Because F# compiler conflict arg0 type inferences: Async<int> or Task<int>.
  let! result = arg0
  let calculated = result + 1
  printfn "%d" calculated
}

// Fixed with type annotation Async<'T> or Task<'T>:
let asyncInner (arg0:Async<_>) = async {
  let! result = arg0
  let calculated = result + 1
  printfn "%d" calculated
}

In C# side:

  • Really need sample codes? huh? :)

Easy LINQPad 5 driven:

  • Before setup NuGet package (FSharp.Control.FusionTasks) the LINQPad NuGet Manager.
open System.IO

// Result is Async<byte[]>
let asyncSequenceData =
  let r = new Random()
  let data = [| for i = 1 to 100 do yield byte (r.Next()) |]
  async {
    use fs = new MemoryStream()
    do! fs.WriteAsync(data, 0, data.Length)
    do! fs.FlushAsync()
    return fs.ToArray()
  }

// Convert to Task<byte[]> and dump:
asyncSequenceData.AsTask().Dump()

LINQPad 5 driven

"task-like" and ValueTask appendix

  • .NET add new "task-like" type. "task-like" means applied a attribute "System.Runtime.CompilerServices.AsyncMethodBuilderAttribute" and declared the async method builder.
  • ValueTask overview:
    • New standard "task-like" type named for "ValueTask<T>" for C#. FusionTasks supported ValueTask<T> on 1.0.20.
    • ValueTask<T> declared by struct (Value type) for goal is improvement performance. But this type has the Task<T> instance inside and finally continuation handle by Task<T>.
    • ValueTask<T> performance effective situation maybe chatty-call fragments using both caller C# and awaiter C# codes...
    • ValueTask<T> a little bit or no effect improvement performance, because usage of senario for FusionTasks.
  • "task-like" augumenting is difficult:
    • We have to apply to task-like type with the attribute "AsyncMethodBuilderAttribute".
    • Means if already declared type (Sure, we have FSharpAsync<'T>) cannot augument and cannot turn to task-like type.
    • Therefore cannot directly return for FSharpAsync<'T> from C#'s async-await method.
    • And cannot auto handle task-like type by FusionTasks, because no type safe declaration for task-like type...
      • For example, if force support task-like type, FusionTasks require augument "Source: taskLike: obj -> FSharpAsync<'T>" overload on FSharpAsync<'T>. This cannot type safe.
  • Conclusion:
    • So FusionTasks support only "ValueTask<T>" type and cannot support any other "task-like" types.

Additional resources

  • Source codes available only "FSharp.Control.FusionTasks" folder.
  • The slides: "How to meets Async and Task" in Seattle F# Users group "MVP Summit Special: A Night of Lightning Talks" 2016.11.09 http://www.slideshare.net/kekyo/asyncs-vs-tasks
<iframe src="https://www.slideshare.net/slideshow/embed_code/68424602" width="800" height="500" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

TODO

Improvements more easier/effective interfaces.

License

History

  • 2.1.1:
    • Downgraded FSharp.Core requirements from 5.0.1 to 5.0.0.
  • 2.1.0:
    • Added .NET 5, .NET Core 3 and .NET Framework 4.8 assemblies.
    • Fixed capturing synchronization context at the asynchronous continuations.
  • 2.0.2:
    • Fixed add xml comments into package.
  • 2.0.1:
    • Add support ValueTask for non-generic version.
    • Fixed XML comments.
  • 2.0.0:
    • Supported F# 4.5, .NET Standard 2.0 and .NET Core 2.0.
    • Sorry, archived all PCL's libraries. Now FusionTasks supports only .NET Framework 4.5, .NET Core 2.0 and .NET Standard 1.6/2.0.
    • Solution structure refablished. Changed to .NET Core modern-style.
  • 1.1.1:
    • Add ValueTask<'T> bind source overload.
  • 1.1.0:
    • Supported F# 4.1 and .NET Standard 1.6. (Unfortunately deprecated FS40.netcore (netstandard1.4) package, try to migrate to F# 4.1 :)
  • 1.0.20:
    • Support ValueTask<T> (Exclude net40 and Profile 47 platform, added dependency for System.Threading.Tasks.Extensions).
    • Update version for .NET Core F# (1.0.0-alpha-161205).
  • 1.0.13:
    • Reduce to only contains .NET Core's assembly in FS40.netcore package.
    • Refactor folder structures.
  • 1.0.12:
    • Add .NET Core support (Separated package: FSharp.Control.FusionTasks.FS40.netcore with -Pre option required)
  • 1.0.2:
    • Support 'for .. in' expressions. (Thx Armin!)
  • 1.0.1:
    • Fixed cause undefined Async<'T> using combination Async<'T> and Task/Task<T> in async workflow. (Thx Honza!)
  • 1.0.0:
    • RTM release 👏
    • Add FSharp.Core NuGet references.
    • Temporary disable support .NET Core. If reached F# RTM, continue development... (PR welcome!!)
    • Add sample codes.
  • 0.9.6:
    • WIP release.
  • 0.9.5:
    • WIP release.
  • 0.9.4:
    • Fixed nuspec reference System, System.Core
  • 0.9.3:
    • Fixed nuspec frameworkAssemblies.
  • 0.9.2:
    • Add package targetFramework.
    • Updated RelaxVersioner.
  • 0.9.1:
    • Remove strongly-signed (Unit test doesn't work...)
    • Omit synchronizers (AsyncLock, AsyncLazy). Thats moving to FSharp.Control.AsyncPrimitives project (https://github.com/kekyo/FSharp.Control.AsyncPrimitives).
    • Add target dnxcore50 into F# 4.0 (for .NET Core 1.0)
    • Source codes and documents bit changed.
  • 0.5.8:
    • Add strongly-signed.
  • 0.5.7:
    • Add PCL Profile 7.
  • 0.5.6:
    • Add PCL Profile 78.
    • Fixed minor PCL moniker fragments.
  • 0.5.5:
    • Fixed version number.
    • Fixed icon image url.
  • 0.5.4:
    • Auto open FSharp.Control.
    • Manage AppVeyor CI.
  • 0.5.3: Implement awaiter classes.
  • 0.5.2: Add dependency assemblies.
  • 0.5.1: NuGet package support.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].