如何在F#中編寫異步WPF(或Windows窗體)事件處理程序?具體來說,是否有任何接近C#5的異步並等待的編碼模式?用於WPF的F#異步事件處理程序類似於C#的異步並等待
這是一個完整的C#WPF應用程序:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
class Program
{
static int IncrementSlowly(int previous)
{
Thread.Sleep(3000);
if (previous == 2) throw new Exception("Oops!");
return previous + 1;
}
static async void btn_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
btn.IsEnabled = false;
try
{
var prev = (int)btn.Content;
btn.Content = await Task.Run(() => IncrementSlowly(prev));
}
catch (Exception ex)
{
btn.Content = ex.Message;
}
finally
{
btn.IsEnabled = true;
}
}
[STAThread]
static void Main(string[] args)
{
var btn = new Button() { Content = 0 };
var win = new Window() { Content = btn };
btn.Click += btn_Click;
new Application().Run(win);
}
}
我有麻煩搞清楚什麼相當於將使用F#。我使用異步工作流和異步方法的組合進行了多次嘗試。它真的很快變得非常混亂。我希望有一個簡單的方法,我只是俯瞰。
這裏是我的出發點,這在btn.Content <- incrementSlowly prev
鎖定了用戶界面。接下來我該做什麼?
open System
open System.Threading
open System.Threading.Tasks
open System.Windows
open System.Windows.Controls
let incrementSlowly previous =
Thread.Sleep(3000)
if previous = 2 then failwith "Oops!"
previous + 1
let btn_Click (sender : obj) e =
let btn = sender :?> Button
btn.IsEnabled <- false
try
try
let prev = btn.Content :?> int
btn.Content <- incrementSlowly prev
with ex -> btn.Content <- ex.Message
finally
btn.IsEnabled <- true
[<EntryPoint>][<STAThread>]
let main _ =
let btn = new Button(Content = 0)
let win = new Window(Content = btn)
btn.Click.AddHandler(RoutedEventHandler(btn_Click))
Application().Run(win)
順便說一下,假設incrementSlowly
不能被修改。
這篇文章應該是有幫助http://tomasp.net/blog/csharp-fsharp- async-intro.aspx/ –