Parallel Programming in F# (IV.): Financial dashboard example
In the fourth part of the Parallel Programming in F# series, we'll take a look at the Adatum Financial Dashboard sample. The sample is a part of Parallel Programming with Microsoft .NET, which is a guide that introduces common parallel programming patterns on .NET 4.0. The C# version of the sample is in details discussed in the guide, but the F# translation contains several additional interesting aspects that I'll introduce in this article.
The sample simulates a financial modelling application that performs processing of market
data in several steps that can be partly executed in parallel. In this article we'll compare two
implementations. The first one (similar to the C# version) uses the Task<'T>
type
from .NET 4.0 and chains steps using the ContinueWith
method. The second version is
F# specific and it implements step as a sequential computation wrapped in asynchronous
workflows. Partial results are reported to the user interface using events.
For discussion about other F# examples from Parallel Programming with Microsoft .NET, you can refer to other parts of this article series. So far, the series covers the following topics:
- Parallel Programming in F# (I.): Introducing the samples
- Parallel Programming in F# (II.): Using PLINQ and Tasks
- Parallel Programming in F# (III.): Aggregating data
- Parallel Programming in F# (IV.): Financial dashboard example
Adatum financial dashboard
The example shows how to develop a financial analysis application that performs several tasks in parallel. The application is created in WPF and uses the MVVM pattern, which separates the declarative user interface (View), a type that exposes data for WPF (ViewModel) and the actual analysis engine (Model).
The application performs analysis of a historical data and yields a market recommendation (to buy or not to buy). It starts by reading data from three data sources, which is an I/O bound task. Next, it merges data from two sources and analyzes them. In parallel, it analyzes data from the third source. The data-flow is displayed on the diagram on the right (adapted from Chapter 5 of Parallel Programming with Microsoft .NET).
The file AnalysisEngine.fs
contains both of the parallel implementations of the calculations
(using .NET 4.0 Task<'T>
type and using F# asynchronous workflows) as well as a
single sequential reference solution. Let's start by looking at the Task-based solution.
Financial Dashboard using Tasks
The key part of the solution is the DoAnalysisParallel
method. It constructs tasks
that call long-running functions that simulate doing some work. For example, loadNyseData
is
I/O intensive and mergeMarketData
, analyzeData
and runModel
are CPU
intensive. In the left branch of the processing (see the diagram), we first start two I/O bound operations:
1: /// Utility function that creates a long running task from F# function 2: let taskLong (f:unit -> 'T) = 3: Task<'T>.Factory.StartNew(new Func<'T>(f), TaskCreationOptions.LongRunning) 4: 5: // Load & process NYSE and NASDAQ data 6: let loadNyseDataTask = taskLong loadNyseData 7: let loadNasdaqDataTask = taskLong loadNasdaqData
The taskLong
function is a simple wrapper that starts a specified F# function
as a task with the LongRunning
flag, which provides a hint to the task scheduler
that the task is I/O bound. We use the function to create two tasks. The first one loads data
from New York Stock Exchange and the second from the NASDAQ Stock Market. Both of the tasks
are values of type Task<StockDataCollection>
. This means that the task will
start running in background and will eventually produce a collection of stock data.
Chaining of tasks
As a next step, we want to create a task that will wait for both of the sources to load and
merge the data into a single collection. When this step is done, we want to continue by running
data normalization using normalizeData
. This can be written as follows:
1: // Create task that merges data when both sources are loaded 2: let mergeMarketDataTask = 3: Task.Factory.ContinueWhenAll 4: ( [| loadNyseDataTask; loadNasdaqDataTask |], 5: fun (tasks:Task<_>[]) -> 6: mergeMarketData [ for t in tasks -> t.Result ]) 7: 8: // Create task that normalizes data when they are merged 9: let normalizeMarketDataTask = 10: mergeMarketDataTask.ContinueWith(fun (t:Task<_>) -> 11: normalizeData(t.Result))
The ContinueWhenAll
method creates a task that will be started when all tasks in the
specified array complete. When that happens, it runs the specified lambda function. Inside the lambda,
we select results of all tasks using a simple list comprehension and merge them.
When the merged task finishes, we want to perform another step - normalize the merged data.
Because we're creating a task that waits only for a single other task, we can use the
ContinueWith
method. The lambda function will be called when the merging is done
and the merged stock data can be accessed via t.Result
. In the complete example,
the normalization of data is followed by several other steps (see the diagram above), but
the implementation follows the pattern presented here.
Handling exceptions
One interesting aspect of the example is error handling.
When an exception occurs anywhere in the code, we want to run a callback provided by the
ViewModel component (to update the GUI). To do that, we need to wait for all the tasks that
form the computation (using ContinueWhenAll
) and then call Task.WaitAll
.
This method throws an exception when any of the awaited tasks throws, so we can use it to get
the error message and log it. In the example, this functionality is wrapped in
createErrorHandler
function which is used as follows:
1: // Construct error handler and return tasks as result 2: let errorHandler = 3: // Merge all tasks, so that we can handle all exceptions 4: createErrorHandler 5: [ loadNyseDataTask; loadNasdaqDataTask; loadFedHistoricalDataTask; 6: mergeMarketDataTask; normalizeHistoricalDataTask; (...) ]
The combined task named errorHandler
will finish when all the tasks of the computation
finish. If an error occurred, the status of the task will be TaskStatus.Faulted
. We
use this fact in the code that registers an error handler. When the task failed, we call the provided
function to report the failure to the user interface. It is also worth noting that we use the
FromCurrentSynchronizationContext
method to create a TaskScheduler
that will invoke the body of the task on the GUI thread, so that the provided function can safely
access WPF components.
Financial Dashboard using Asyncs
The dashboard application combines I/O and CPU intensive tasks, so F# asynchronous workflows
may be actually a better choice than tasks. I/O intensive operation in the task-based solution
such as loadNyseData
blocks the calling thread, but do not fully utilize the thread.
When using asynchronous workflows, we'll use asyncLoadNyseData
, which is a
non-blocking version of the function.
We'll write the computation as a single asynchronous workflow that will produce the final decision (to buy or not to buy). However, the application also requires some intermediate results, so we'll need to report results of various steps in the computation. To do that, we'll use events...
Notifying user interface
As already mentioned, we'll use events to notify the user interface of intermediate results,
so we need to start by declaring several events. The following snippet includes only those that
will be used in the larger sample below (implementing the left branch of the above diagram).
In addition, we'll need two utility functions. The function triggerGuiEvent
uses WPF Dispatcher
type to invoke the specified event on the main GUI
thread, so that the listener can safely access user interface controls. The function
triggerWhenCompleted
is used to create asynchronous workflow that triggers
the specified event on completion:
1: /// Trigger event on the GUI thread using a captured dispatcher 2: let triggerGuiEvent (e:Event<_>) v = 3: guiDispatch.Invoke(new Action(fun () -> e.Trigger(v) ), [| |]) |> ignore 4: 5: /// Constructs workflow that triggers the specified event 6: /// on the GUI thread when the wrapped async completes 7: let triggerWhenCompletes (e:Event<_>) (a:Async<_>) = async { 8: let! res = a 9: triggerGuiEvent e res 10: return res } 1: // Create events that are used to report progress to the GUI 2: let loadNyseDataEvt = new Event<_>() 3: let loadNasdaqDataEvt = new Event<_>() 4: let mergeMarketDataEvt = new Event<_>() 5: let normalizeMarketDataEvt = new Event<_>() 6: let analyzeMarketDataEvt = new Event<_>() 7: let modelMarketDataEvt = new Event<_>() 8: let compareModelsEvt = new Event<_>() 9: let errorHandlerEvt = new Event<_>()
The implementation of triggerGuiEvent
uses an instance guiDispatch
that is captured by the AnalysisEngine
when it is created on the main thread.
The second helper function is slightly more interesting - it is implemented as an asynchronous
workflow that calls the provided workflow, then triggers the given event and finally returns
the original result. The function actually just wraps a specified workflow into another workflow
that also triggers the event.
Implementing workflow
Now that we have all the utility functions and events, we can look at the most important part of the code - the workflow that performs the computation and reports results to the user interface. This part of the code corresponds to the code that constructs and chains tasks in the previous implementation.
The workflow first needs to download data from the two data sources in parallel. This is done
using the Async.StartChild
function, which starts the workflow as a task in background
and give us another async that can be used to retrieve the result. Once we get both of the
inputs, we can run the rest of the processing as a sequential asynchronous code. In the
complete application, this will run in parallel with the other branch.
1: // Load & process NYSE and NASDAQ data 2: let marketModel = async { 3: // Start loading of data from two sources in background (both I/O 4: // operations are perfomed asynchronously without blocking threads) 5: let nyseWork = asyncLoadNyseData() |> triggerWhenCompletes loadNyseDataEvt 6: let nasdaqWork = asyncLoadNasdaqData() |> triggerWhenCompletes loadNasdaqDataEvt 7: let! nyse = nyseWork |> Async.StartChild 8: let! nasdaq = nasdaqWork |> Async.StartChild 9: 10: // Wait for both tasks to complete and continue 11: let! nyseData = nyse 12: let! nasdaqData = nasdaq 13: let merged = mergeMarketData [ nyseData; nasdaqData ] 14: triggerGuiEvent mergeMarketDataEvt merged 15: 16: // Perform analysis of the merged data 17: let normalized = normalizeData merged 18: triggerGuiEvent normalizeMarketDataEvt normalized 19: let analyzed = analyzeData normalized 20: triggerGuiEvent analyzeMarketDataEvt analyzed 21: let res = runModel analyzed 22: triggerGuiEvent modelMarketDataEvt res 23: return res }
In the first part of the workflow, we first create two workflows that will be executed
in parallel to download stock data from NYSE and NASDAQ. We use the asynchronous version of
a function for loading data and wrap the resulting workflow into a workflow that triggers an
event when the loading completes (using triggerWhenCompletes
). Then we start
both of the workflows in parallel using Async.StartChild
and wait until both
of them complete (using let!
to get the result asynchronously).
The second part of the workflow is fully sequential. We perform all the remaining steps
(merge the data, normalize the result, analyze the data and run the data model). After each
step, we report the result to the user interface by triggering one of the events (we use
triggerGuiEvent
to schedule the triggering via message queue). Note that
the second part of the workflow does not contain any yield points (e.g. let!
),
so it will run as a CPU-intensive computation.
Comparing models and exception handling
In the task-based version, we spent some time discussing code that implements exception handling,
because we need to write it explicitly by waiting for all tasks. When using asynchronous
workflows in F#, the situation is a lot simpler - we can simply use try ... with
construct to handle any exceptions. Even when the exception is thrown by another workflow that
we use (or invoke using Async.StartChild
), the exception will be automatically
propagated.
In the next example, we'll look at the last piece of code that builds the complete workflow
for the processing. We'll use the marketModel
workflow declared above and a
workflow historicalModel
that represents the other branch. We'll want to run these
two workflows in parallel to get two models for a comparison, compare them and report
the result to the user interface. When an exception occurs, we want to report it to the
GUI using the same mechanism:
1: let compare = async { 2: try 3: // Run both of the models and compare them to get recommendation 4: let! models = Async.Parallel [ marketModel; historicalModel ] 5: let res = compareModels models 6: triggerGuiEvent compareModelsEvt res 7: with e -> 8: // Report error to the user interface 9: triggerGuiEvent errorHandlerEvt () }
To run the two models in parallel, we use Async.Parallel
to create a single
workflow that runs both of them. Then we wait for the result using let!
As a result,
we'll get an array of models called models
, which can be directly passed to the
compareModels
function. As you can see, adding exception handling is very straightforward,
because we just wrapped the whole code inside the try ... with
block and we
trigger the error handler event in the with
clause.
Summary
In this article, we looked at two F# implementations of the Adatum financial dashboard sample application from Parallel Programming with Microsoft .NET. The first version was a direct translation of a C# sample and used .NET 4.0 tasks. The second version was built using F# asynchronous workflows. The notable differences between the two versions are following:
- Asynchronous workflows offer better scalability for I/O bound operations. When loading data from stock exchanges, asynchronous workflows use thread pool threads for non-blocking I/O, while the task based solution requires one thread for each of the operations.
- Exception handling is easier in the version based on asynchronous workflows. The exception
is automatically propagated and can be handled using the natural
try ... with
construct. - Reporting results to the user interface is slightly easier in the Task-based solution. The result of the task can be accessed at any time after the task finished, while asynchronous workflows invoke the notification once (and the result would have to be cached by the caller).
The choice between the two possible implementations depends on many factors. Asynchronous workflows were designed specifically for F#, so they more naturally fit with the language. They offer better performance for I/O bound tasks and provide more convenient exception handling. Moreover, the sequential syntax is quite convenient. On the other hand, tasks are optimized for CPU bound calculations and make it easier to access the result of calculation from other places of the application without explicit caching.
Downloads and References
- Parallel Programming with Microsoft .NET - Book homepage at CodePlex
- F# Code Samples - Parallel Programming with Microsoft .NET
Trigger event on the GUI thread using a captured dispatcher
module Event
from Microsoft.FSharp.Control
--------------------
type Event<'Delegate,'Args (requires delegate and 'Delegate :> Delegate)> =
class
new : unit -> Event<'Delegate,'Args>
member Trigger : sender:obj * args:'Args -> unit
member Publish : IEvent<'Delegate,'Args>
end
Full name: Microsoft.FSharp.Control.Event<_,_>
--------------------
type Event<'T> =
class
new : unit -> Event<'T>
member Trigger : arg:'T -> unit
member Publish : IEvent<'T>
end
Full name: Microsoft.FSharp.Control.Event<_>
Windows.Threading.Dispatcher.Invoke(method: Delegate, args: obj []) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, method: Delegate) : obj
Windows.Threading.Dispatcher.Invoke(method: Delegate, timeout: TimeSpan, args: obj []) : obj
Windows.Threading.Dispatcher.Invoke(method: Delegate, priority: Windows.Threading.DispatcherPriority, args: obj []) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, timeout: TimeSpan, method: Delegate) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, method: Delegate, arg: obj) : obj
Windows.Threading.Dispatcher.Invoke(method: Delegate, timeout: TimeSpan, priority: Windows.Threading.DispatcherPriority, args: obj []) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, timeout: TimeSpan, method: Delegate, arg: obj) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, method: Delegate, arg: obj, args: obj []) : obj
Windows.Threading.Dispatcher.Invoke(priority: Windows.Threading.DispatcherPriority, timeout: TimeSpan, method: Delegate, arg: obj, args: obj []) : obj
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> unit
Full name: System.Action<_,_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> unit
Full name: System.Action<_,_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6,'T7>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5,'T6> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> unit
Full name: System.Action<_,_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5,'T6>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4,'T5> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> unit
Full name: System.Action<_,_,_,_,_>
type: Action<'T1,'T2,'T3,'T4,'T5>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3,'T4> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 -> unit
Full name: System.Action<_,_,_,_>
type: Action<'T1,'T2,'T3,'T4>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2,'T3> =
delegate of 'T1 * 'T2 * 'T3 -> unit
Full name: System.Action<_,_,_>
type: Action<'T1,'T2,'T3>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T1,'T2> =
delegate of 'T1 * 'T2 -> unit
Full name: System.Action<_,_>
type: Action<'T1,'T2>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action<'T> =
delegate of 'T -> unit
Full name: System.Action<_>
type: Action<'T>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Action =
delegate of unit -> unit
Full name: System.Action
type: Action
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> 'T15 -> 'T16 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> 'T15 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> 'T4 -> unit)
--------------------
Action('T1 -> 'T2 -> 'T3 -> unit)
--------------------
Action('T1 -> 'T2 -> unit)
--------------------
Action('T -> unit)
--------------------
Action(unit -> unit)
Full name: Microsoft.FSharp.Core.Operators.ignore
Constructs workflow that triggers the specified event
on the GUI thread when the wrapped async completes
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
--------------------
type Async
with
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
end
Full name: Microsoft.FSharp.Control.Async
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
Utility function that creates a long running task from F# function
Full name: Microsoft.FSharp.Core.unit
type: unit
implements: IComparable
type Task<'TResult> =
class
inherit System.Threading.Tasks.Task
new : System.Func<'TResult> -> System.Threading.Tasks.Task<'TResult>
new : System.Func<'TResult> * System.Threading.CancellationToken -> System.Threading.Tasks.Task<'TResult>
new : System.Func<'TResult> * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task<'TResult>
new : System.Func<'TResult> * System.Threading.CancellationToken * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task<'TResult>
new : System.Func<obj,'TResult> * obj -> System.Threading.Tasks.Task<'TResult>
new : System.Func<obj,'TResult> * obj * System.Threading.CancellationToken -> System.Threading.Tasks.Task<'TResult>
new : System.Func<obj,'TResult> * obj * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task<'TResult>
new : System.Func<obj,'TResult> * obj * System.Threading.CancellationToken * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task<'TResult>
member ContinueWith : System.Action<System.Threading.Tasks.Task<'TResult>> -> System.Threading.Tasks.Task
member ContinueWith<'TNewResult> : System.Func<System.Threading.Tasks.Task<'TResult>,'TNewResult> -> System.Threading.Tasks.Task<'TNewResult>
member ContinueWith : System.Action<System.Threading.Tasks.Task<'TResult>> * System.Threading.CancellationToken -> System.Threading.Tasks.Task
member ContinueWith : System.Action<System.Threading.Tasks.Task<'TResult>> * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task
member ContinueWith : System.Action<System.Threading.Tasks.Task<'TResult>> * System.Threading.Tasks.TaskContinuationOptions -> System.Threading.Tasks.Task
member ContinueWith<'TNewResult> : System.Func<System.Threading.Tasks.Task<'TResult>,'TNewResult> * System.Threading.CancellationToken -> System.Threading.Tasks.Task<'TNewResult>
member ContinueWith<'TNewResult> : System.Func<System.Threading.Tasks.Task<'TResult>,'TNewResult> * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task<'TNewResult>
member ContinueWith<'TNewResult> : System.Func<System.Threading.Tasks.Task<'TResult>,'TNewResult> * System.Threading.Tasks.TaskContinuationOptions -> System.Threading.Tasks.Task<'TNewResult>
member ContinueWith : System.Action<System.Threading.Tasks.Task<'TResult>> * System.Threading.CancellationToken * System.Threading.Tasks.TaskContinuationOptions * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task
member ContinueWith<'TNewResult> : System.Func<System.Threading.Tasks.Task<'TResult>,'TNewResult> * System.Threading.CancellationToken * System.Threading.Tasks.TaskContinuationOptions * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task<'TNewResult>
member Result : 'TResult with get, set
static member Factory : System.Threading.Tasks.TaskFactory<'TResult>
end
Full name: System.Threading.Tasks.Task<_>
type: Task<'TResult>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
--------------------
type Task =
class
new : System.Action -> System.Threading.Tasks.Task
new : System.Action * System.Threading.CancellationToken -> System.Threading.Tasks.Task
new : System.Action * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task
new : System.Action * System.Threading.CancellationToken * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task
new : System.Action<obj> * obj -> System.Threading.Tasks.Task
new : System.Action<obj> * obj * System.Threading.CancellationToken -> System.Threading.Tasks.Task
new : System.Action<obj> * obj * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task
new : System.Action<obj> * obj * System.Threading.CancellationToken * System.Threading.Tasks.TaskCreationOptions -> System.Threading.Tasks.Task
member AsyncState : obj
member ContinueWith : System.Action<System.Threading.Tasks.Task> -> System.Threading.Tasks.Task
member ContinueWith<'TResult> : System.Func<System.Threading.Tasks.Task,'TResult> -> System.Threading.Tasks.Task<'TResult>
member ContinueWith : System.Action<System.Threading.Tasks.Task> * System.Threading.CancellationToken -> System.Threading.Tasks.Task
member ContinueWith : System.Action<System.Threading.Tasks.Task> * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task
member ContinueWith : System.Action<System.Threading.Tasks.Task> * System.Threading.Tasks.TaskContinuationOptions -> System.Threading.Tasks.Task
member ContinueWith<'TResult> : System.Func<System.Threading.Tasks.Task,'TResult> * System.Threading.CancellationToken -> System.Threading.Tasks.Task<'TResult>
member ContinueWith<'TResult> : System.Func<System.Threading.Tasks.Task,'TResult> * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task<'TResult>
member ContinueWith<'TResult> : System.Func<System.Threading.Tasks.Task,'TResult> * System.Threading.Tasks.TaskContinuationOptions -> System.Threading.Tasks.Task<'TResult>
member ContinueWith : System.Action<System.Threading.Tasks.Task> * System.Threading.CancellationToken * System.Threading.Tasks.TaskContinuationOptions * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task
member ContinueWith<'TResult> : System.Func<System.Threading.Tasks.Task,'TResult> * System.Threading.CancellationToken * System.Threading.Tasks.TaskContinuationOptions * System.Threading.Tasks.TaskScheduler -> System.Threading.Tasks.Task<'TResult>
member CreationOptions : System.Threading.Tasks.TaskCreationOptions
member Dispose : unit -> unit
member Exception : System.AggregateException
member Id : int
member IsCanceled : bool
member IsCompleted : bool
member IsFaulted : bool
member RunSynchronously : unit -> unit
member RunSynchronously : System.Threading.Tasks.TaskScheduler -> unit
member Start : unit -> unit
member Start : System.Threading.Tasks.TaskScheduler -> unit
member Status : System.Threading.Tasks.TaskStatus
member Wait : unit -> unit
member Wait : System.TimeSpan -> bool
member Wait : System.Threading.CancellationToken -> unit
member Wait : int -> bool
member Wait : int * System.Threading.CancellationToken -> bool
static member CurrentId : System.Nullable<int>
static member Factory : System.Threading.Tasks.TaskFactory
static member WaitAll : System.Threading.Tasks.Task [] -> unit
static member WaitAll : System.Threading.Tasks.Task [] * System.TimeSpan -> bool
static member WaitAll : System.Threading.Tasks.Task [] * int -> bool
static member WaitAll : System.Threading.Tasks.Task [] * System.Threading.CancellationToken -> unit
static member WaitAll : System.Threading.Tasks.Task [] * int * System.Threading.CancellationToken -> bool
static member WaitAny : System.Threading.Tasks.Task [] -> int
static member WaitAny : System.Threading.Tasks.Task [] * System.TimeSpan -> int
static member WaitAny : System.Threading.Tasks.Task [] * System.Threading.CancellationToken -> int
static member WaitAny : System.Threading.Tasks.Task [] * int -> int
static member WaitAny : System.Threading.Tasks.Task [] * int * System.Threading.CancellationToken -> int
end
Full name: System.Threading.Tasks.Task
type: Task
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'TResult
Full name: System.Func<_,_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'T6,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'TResult
Full name: System.Func<_,_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'T5,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'T4,'TResult> =
delegate of 'T1 * 'T2 * 'T3 * 'T4 -> 'TResult
Full name: System.Func<_,_,_,_,_>
type: Func<'T1,'T2,'T3,'T4,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'T3,'TResult> =
delegate of 'T1 * 'T2 * 'T3 -> 'TResult
Full name: System.Func<_,_,_,_>
type: Func<'T1,'T2,'T3,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T1,'T2,'TResult> =
delegate of 'T1 * 'T2 -> 'TResult
Full name: System.Func<_,_,_>
type: Func<'T1,'T2,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'T,'TResult> =
delegate of 'T -> 'TResult
Full name: System.Func<_,_>
type: Func<'T,'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
type Func<'TResult> =
delegate of unit -> 'TResult
Full name: System.Func<_>
type: Func<'TResult>
implements: ICloneable
implements: Runtime.Serialization.ISerializable
inherits: MulticastDelegate
inherits: Delegate
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> 'T15 -> 'T16 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> 'T15 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'T14 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'T13 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'T12 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'T11 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'T10 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'T9 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'T8 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'T7 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'T6 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'T5 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'T4 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'T3 -> 'TResult)
--------------------
Func('T1 -> 'T2 -> 'TResult)
--------------------
Func('T -> 'TResult)
--------------------
Func(unit -> 'TResult)
| None = 0
| PreferFairness = 1
| LongRunning = 2
| AttachedToParent = 4
Full name: System.Threading.Tasks.TaskCreationOptions
type: TaskCreationOptions
inherits: Enum
inherits: ValueType
type: StockDataCollection
implements: IList<StockData>
implements: ICollection<StockData>
implements: seq<StockData>
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IEnumerable
inherits: Collections.ObjectModel.ReadOnlyCollection<StockData>
type: StockDataCollection
implements: IList<StockData>
implements: ICollection<StockData>
implements: seq<StockData>
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IEnumerable
inherits: Collections.ObjectModel.ReadOnlyCollection<StockData>
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
property Task.Factory: TaskFactory
--------------------
property Task.Factory: TaskFactory<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult,'TResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TResult>(tasks: Task [], continuationFunction: Func<Task [],'TResult>) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationAction: Action<Task<'TAntecedentResult> []>) : Task
TaskFactory.ContinueWhenAll(tasks: Task [], continuationAction: Action<Task []>) : Task
TaskFactory.ContinueWhenAll<'TAntecedentResult,'TResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult,'TResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TResult>(tasks: Task [], continuationFunction: Func<Task [],'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TResult>(tasks: Task [], continuationFunction: Func<Task [],'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationAction: Action<Task<'TAntecedentResult> []>, continuationOptions: TaskContinuationOptions) : Task
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationAction: Action<Task<'TAntecedentResult> []>, cancellationToken: CancellationToken) : Task
(+6 other overloads)
--------------------
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>) : Task<'TResult>
TaskFactory.ContinueWhenAll(tasks: Task [], continuationFunction: Func<Task [],'TResult>) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
TaskFactory.ContinueWhenAll(tasks: Task [], continuationFunction: Func<Task [],'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
TaskFactory.ContinueWhenAll(tasks: Task [], continuationFunction: Func<Task [],'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
TaskFactory.ContinueWhenAll<'TAntecedentResult>(tasks: Task<'TAntecedentResult> [], continuationFunction: Func<Task<'TAntecedentResult> [],'TResult>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task<'TResult>
TaskFactory.ContinueWhenAll(tasks: Task [], continuationFunction: Func<Task [],'TResult>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task<'TResult>
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockDataCollection> []
implements: ICloneable
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IStructuralComparable
implements: Collections.IStructuralEquatable
implements: IList<Task<StockDataCollection>>
implements: ICollection<Task<StockDataCollection>>
implements: seq<Task<StockDataCollection>>
implements: Collections.IEnumerable
inherits: Array
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>) : Task
Task.ContinueWith<'TNewResult>(continuationFunction: Func<Task<StockDataCollection>,'TNewResult>) : Task<'TNewResult>
Task.ContinueWith(continuationAction: Action<Task<StockDataCollection>>) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, continuationOptions: TaskContinuationOptions) : Task
Task.ContinueWith(continuationAction: Action<Task>, scheduler: TaskScheduler) : Task
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken) : Task
(+10 other overloads)
type: Task<unit>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockDataCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockAnalysisCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<StockAnalysisCollection>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<MarketModel>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<MarketModel>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
type: Task<MarketRecommendation>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>) : Task
Task.ContinueWith<'TNewResult>(continuationFunction: Func<Task<unit>,'TNewResult>) : Task<'TNewResult>
Task.ContinueWith(continuationAction: Action<Task<unit>>) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, continuationOptions: TaskContinuationOptions) : Task
Task.ContinueWith(continuationAction: Action<Task>, scheduler: TaskScheduler) : Task
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken) : Task
(+10 other overloads)
type: Task<unit>
implements: IThreadPoolWorkItem
implements: IAsyncResult
implements: IDisposable
inherits: Task
| Created = 0
| WaitingForActivation = 1
| WaitingToRun = 2
| Running = 3
| WaitingForChildrenToComplete = 4
| RanToCompletion = 5
| Canceled = 6
| Faulted = 7
Full name: System.Threading.Tasks.TaskStatus
type: TaskStatus
inherits: Enum
inherits: ValueType
class
member Id : int
member MaximumConcurrencyLevel : int
static member Current : System.Threading.Tasks.TaskScheduler
static member Default : System.Threading.Tasks.TaskScheduler
static member FromCurrentSynchronizationContext : unit -> System.Threading.Tasks.TaskScheduler
end
Full name: System.Threading.Tasks.TaskScheduler
type: StockDataCollection
implements: IList<StockData>
implements: ICollection<StockData>
implements: seq<StockData>
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IEnumerable
inherits: Collections.ObjectModel.ReadOnlyCollection<StockData>
type: StockDataCollection
implements: IList<StockData>
implements: ICollection<StockData>
implements: seq<StockData>
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IEnumerable
inherits: Collections.ObjectModel.ReadOnlyCollection<StockData>
type: StockAnalysisCollection
implements: IList<StockAnalysis>
implements: ICollection<StockAnalysis>
implements: seq<StockAnalysis>
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IEnumerable
inherits: Collections.ObjectModel.ReadOnlyCollection<StockAnalysis>
type: MarketModel []
implements: ICloneable
implements: Collections.IList
implements: Collections.ICollection
implements: Collections.IStructuralComparable
implements: Collections.IStructuralEquatable
implements: IList<MarketModel>
implements: ICollection<MarketModel>
implements: seq<MarketModel>
implements: Collections.IEnumerable
inherits: Array
type: exn
implements: Runtime.Serialization.ISerializable
implements: Runtime.InteropServices._Exception
Published: Monday, 6 September 2010, 10:30 AM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: functional, parallel, asynchronous, f#