FCell makes it possible to run .NET UDFs asynchronously. Asynchronous functions run in the background without blocking Excel UI and Excel will show #WAIT while the function is running. When the function returns, its result will be shown in Excel or #VALUE if an exception was thrown.

You can also subscribe a cell or Excel range to a stream of events by creating UDF which returns IObservable<'T> or F# IEvent<'T>

There are 2 different ways to implement asynchronous functions in FCell.

Asynchronous UDFs with F# async

If your F# function returns async<'T>> then the function will be exposed as UDF and run asynchronously without blocking Excel UI.

Note

FCell asynchronous functions depend on Excel RTD functionality.

Note

FCell asynchronous functions cannot depend directly or indirectly on Excel volatile functions, e.g. rand.

F# Copy imageCopy
let asyncFun x = async{do! Async.Sleep(4000)
                       return x + 1
                      }

Asynchronous UDFs with [XlAsync] attribute

If your .NET method is marked with an [XlAsync] attribute, it will run on a background thread without blocking Excel UI.

Note

FCell asynchronous functions depend on Excel RTD functionality.

F# Copy imageCopy
open FCell.ManagedXll
open System

module AsyncUdfs =
    [<XlAsync>]
    let asyncFun x = 
        let mutable res = 0.0
        for i in 0..100000000 do
            res <- res + Math.Sin(x)
        res
C# Copy imageCopy
using FCell.ManagedXll;
using System;

public class AsyncUdfs
{
    [XlAsync]
    public static Double AsyncFun(Double x)
    {
        var res = 0.0;
        for (int i = 0; i < 100000000; i++)
        {
            res = res + Math.Sin(x);
        }
        return res;
    }
}
Visual Basic Copy imageCopy
Imports FCell.ManagedXll

Module AsyncUdfs
    <XlAsync>
    Public Function AsyncFun(ByVal x As Double) As Double
        Dim res = 0
        For i As Integer = 0 To 100000000
            res = res + Math.Sin(x)
        Next
        Return res
    End Function
End Module

Subscribing to stream of events: returning IObservable<'T> or F# IEvent<'T>

If your .NET function returns IObservable<'T> or F# IEvent<'T> then the function will be exposed as UDF and asynchronously show every new value 'T from the stream of events.

Note

FCell reactive functions depend on Excel RTD functionality.

Note

If you want to use Rx library (free download from Microsoft) you will need to add Rx bin folder to FCell .NET Search Folders. You can also embed Rx assemblies as References via Doc .NET AddIn.

F# Copy imageCopy
open System.Reactive
open System.Reactive.Linq
open System

module RxUdfs =

    let event = new Event<_>()

    do async{for i in 0..100 do
                 do! Async.Sleep(2000)
                 event.Trigger(i)
            } |> Async.StartImmediate

    let getLast() = event.Publish

    let rxUdf(n) = Observable.Interval(TimeSpan.FromSeconds(n))
C# Copy imageCopy
using System.Reactive;
using System.Reactive.Linq;
using System;

public class RxUdfs
{
    public static IObservable<Int64> RxUdf(Double n)
    {
        return Observable.Interval(TimeSpan.FromSeconds(n));
    }
}
Visual Basic Copy imageCopy
Imports System.Reactive
Imports System.Reactive.Linq

Module RxUdfs
    Public Function RxUdf(ByVal n As Double) As IObservable(Of Int64)
        Return Observable.Interval(TimeSpan.FromSeconds(n))
    End Function
End Module