这个问题一直让我抓狂。总体要点如下:
我的解决方案中有两个项目:第一个是 F# 控制台应用程序,第二个是 C# 库,其中包含名为的 C#+XAML 类DisplayWindow
继承自 WPF 窗口。DisplayWindow
有一个方法public void SetMessage(string s) {...}
这使得窗口以大而闪亮的字母显示传递给它的文本,这些字母可能还会闪烁和旋转,并执行 WPF 擅长的其他所有操作。
问题是:我需要从我的 F# 程序中创建一个函数let openAWindow text = ???
以便它将打开一个新的DisplayWindow
每次与文本一起调用时都是异步的。做这个的最好方式是什么?使用async {}
or System.Threading.Thread
?谢谢您的帮助 :)
编辑:我找到了这篇博文http://deanchalk.com/2010/10/08/f-interacting-with-wpf-dispatcher-via-f-interactive-window/可以工作,但有时(?)会导致 ArgumentException 并显示错误文本“具有相同键的条目已存在。”所以我不知道那里发生了什么:(
我这样做是为了我们的F# 用于可视化图书馆,然后描述了我在书中使用的技术用于技术计算的 Visual F# 2010.
首先,我编写了一个惰性 thunk 来初始化 WPF(包括 STA UI 线程和Application
) 当强制求值时:
> let ui =
let mk() =
let wh = new ManualResetEvent(false)
let application = ref null
let start() =
let app = Application()
application := app
ignore(wh.Set())
app.Run() |> ignore
let thread = Thread start
thread.IsBackground <- true
thread.SetApartmentState ApartmentState.STA
thread.Start()
ignore(wh.WaitOne())
!application, thread
lazy(mk());;
val ui : Lazy<Application * Thread> = <unevaluated>
然后我写了一个spawn
调度函数应用程序的函数f
争论x
这样它就在 UI 线程上运行:
> let spawn : ('a -> 'b) -> 'a -> 'b =
fun f x ->
let app, thread = ui.Force()
let f _ =
try
let f_x = f x
fun () -> f_x
with e ->
fun () -> raise e
let t = app.Dispatcher.Invoke(DispatcherPriority.Send, System.Func<_, _>(f), null)
(t :?> unit -> 'b)();;
val spawn : ('a -> 'b) -> 'a -> 'b
现在只需调用您的openAWindow
UI 线程上的函数:
let openAWindow text =
DisplayWindow().SetMessage text
spawn openAWindow text
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)