Чтобы получить преимущества асинхронного рабочего процесса F #, вы должны написать асинхронные вычисления на F #.Код, который вы пытаетесь написать, не будет работать (т.е. он может выполняться, но не будет полезен).
Когда вы пишете асинхронные вычисления в F #, вы можете делать асинхронные вызовы, используя let!
и do!
.Это позволяет вам использовать другие примитивные неблокирующие вычисления.Например, вы можете использовать Async.Sleep
вместо Thread.Sleep
.
// This is a synchronous call that will block thread for 1 sec
async { do Thread.Sleep(1000)
someMoreStuff() }
// This is an asynchronous call that will not block threads - it will create
// a timer and when the timer elapses, it will call 'someMoreStuff'
async { do! Async.Sleep(1000)
someMoreStuff() }
Вы можете использовать только асинхронные операции внутри блока async
, и это зависит от способа обработки компилятором F # do!
и let!
.Нет (простого) способа получить реальное неблокирующее выполнение для кода, который написан последовательным способом (например, в C # или вне блока async
в F #).
Если вы хотите использовать F # дляПолучите преимущества асинхронных рабочих процессов, тогда лучшим вариантом будет реализовать операции в F #, а затем представить их на C #, используя Async.StartAsTask
(что дает вам Task<T>
, который C # может легко использовать).Примерно так:
let someFunction(n) = async {
do! Async.Sleep(n)
Console.WriteLine("working")
do! Async.Sleep(n)
Console.WriteLine("done")
return 10 }
type AsyncStuff() =
member x.Foo(n) = someFunction(n) |> Async.StartAsTask
// In C#, you can write:
var as = new AsyncStuff()
as.Foo(1000).ContinueWith(op =>
// 'Value' will throw if there was an exception
Console.WriteLine(op.Value))
Если вы не хотите использовать F # (по крайней мере, для реализации ваших асинхронных вычислений), то асинхронные рабочие процессы вам не помогут.Вы можете реализовать аналогичную вещь, используя Task
, BackgroundWorker
или другие технологии C # (но вы потеряете возможность легко выполнять операции без блокировки потоков).