Async.TryCancelled<'T> 方法 (F#)
创建执行指定计算函数的异步计算。 如果此计算在完成之前被取消,则将执行通过运行补偿功能生成的计算。
命名空间/模块路径:Microsoft.FSharp.Control
程序集:FSharp.Core(在 FSharp.Core.dll 中)
// Signature:
static member TryCancelled : Async<'T> * (OperationCanceledException -> unit) -> Async<'T>
// Usage:
Async.TryCancelled (computation, compensation)
参数
computation
类型:Async<'T>输入异步计算。
compensation
类型:OperationCanceledException -> unit取消计算时要运行的函数。
返回值
取消输入计算时运行补偿的异步计算。
示例
以下代码示例演示如何使用 Async.TryCancelled 来运行可取消的计算。
open System
open System.Windows.Forms
let form = new Form(Text = "Test Form", Width = 400, Height = 400)
let panel1 = new Panel(Dock = DockStyle.Fill)
panel1.DockPadding.All <- 10
let spacing = 5
let startAsyncButton = new Button(Text = "Start", Enabled = true)
let controlHeight = startAsyncButton.Height
let button2 = new Button(Text = "Start Invalid", Top = controlHeight + spacing)
let cancelAsyncButton = new Button(Text = "Cancel",
Top = 2 * (controlHeight + spacing),
Enabled = false)
let updown1 = new System.Windows.Forms.NumericUpDown(Top = 3 * (controlHeight + spacing),
Value = 20m, Minimum = 0m,
Maximum = 1000000m)
let label1 = new Label (Text = "", Top = 4 * (controlHeight + spacing),
Width = 300, Height = 2 * controlHeight)
let progressBar = new ProgressBar(Top = 6 * (controlHeight + spacing),
Width = 300)
panel1.Controls.AddRange [| startAsyncButton; button2; cancelAsyncButton;
updown1; label1; progressBar; |]
form.Controls.Add(panel1)
// Recursive isprime function.
let isprime number =
let rec check count =
count > number/2 || (number % count <> 0 && check (count + 1))
check 2
let isprimeBigInt number =
let rec check count =
count > number/2I || (number % count <> 0I && check (count + 1I))
check 2I
let computeNthPrime (number) =
if (number < 1) then
invalidOp <| sprintf "Invalid input for nth prime: %s." (number.ToString())
let mutable count = 0
let mutable num = 1I
let isDone = false
while (count < number) do
num <- num + 1I
if (num < bigint System.Int32.MaxValue) then
while (not (isprime (int num))) do
num <- num + 1I
else
while (not (isprimeBigInt num)) do
num <- num + 1I
count <- count + 1
num
let async1 context value =
let asyncTryWith =
async {
try
let nthPrime = ref 0I
for count in 1 .. value - 1 do
// The cancellation check is implicit and
// cooperative at for!, do!, and so on.
nthPrime := computeNthPrime(count)
// Report progress as a percentage of the total task.
let percentComplete = (int)((float)count /
(float)value * 100.0)
do! Async.SwitchToContext(context)
progressBar.Value <- percentComplete
do! Async.SwitchToThreadPool()
// Handle the case in which the operation succeeds.
do! Async.SwitchToContext(context)
label1.Text <- sprintf "%s" ((!nthPrime).ToString())
with
| e ->
// Handle the case in which an exception is thrown.
do! Async.SwitchToContext(context)
MessageBox.Show(e.Message) |> ignore
}
async {
try
do! Async.TryCancelled(asyncTryWith,
(fun oce ->
// Handle the case in which the user cancels the operation.
context.Post((fun _ ->
label1.Text <- "Canceled"), null)))
finally
context.Post((fun _ ->
updown1.Enabled <- true
startAsyncButton.Enabled <- true
cancelAsyncButton.Enabled <- false),
null)
}
startAsyncButton.Click.Add(fun args ->
cancelAsyncButton.Enabled <- true
let context = System.Threading.SynchronizationContext.Current
Async.Start(async1 context (int updown1.Value)))
button2.Click.Add(fun args ->
let context = System.Threading.SynchronizationContext.Current
Async.Start(async1 context (int (-updown1.Value))))
cancelAsyncButton.Click.Add(fun args -> Async.CancelDefaultToken())
Application.Run(form)
平台
Windows 8,Windows 7,Windows server 2012中,Windows server 2008 R2
版本信息
F#核心库版本
支持:2.0,4.0,可移植