如何在不阻塞控制台的情况下,使用.Net(C#/F#)在控制台应用程序的新窗口中显示不断变化的(动画)图像



我正在尝试在.Net中构建一个starcraft2 AI,我想显示一个包含一些实时特征图数据的窗口。人工智能是从控制台应用程序运行的,我希望保持这种状态。我想让我的代码吐出一些位图数据,显示在窗口中,因为人工智能是实时的。然而,从这个答案来看,从控制台应用程序运行表单似乎会阻塞控制台线程。

如何从控制台应用程序运行表单并定期向其传递位图?我在F#中做这件事,但很高兴看到基于C#或VB.Net的答案,因为我可以根据需要进行翻译。

我不想尝试将其作为Windows应用程序来运行以显示表单,然后让我的人工智能从那里运行,因为在某个时候,我可能想在梯子上与我的AI竞争,我不确定是否支持Windows表单应用程序。

我想我可以让我的控制台应用程序通过zero-mq或其他方式发布数据,然后任何碰巧正在侦听的进程都可以显示它,但对于一个简单的需求来说,这似乎有点复杂。如果没有更好(更容易(的解决方案,我会认为这就是答案。

下面是一个使用F#MailboxProcessor并在单独的线程上托管表单的工作示例。这使用了一个文本框而不是图像,但这是相同的想法。

module ConsoleApp 
open System
open System.Windows.Forms
type WinForm () as form =
inherit Form ()
let textBox = new TextBox()
do form.Controls.Add(textBox)
member __.SetText text = textBox.Text <- text
type Message = SetText of string
type UpdateText = delegate of unit -> unit
let form = new WinForm()    
let agent =
MailboxProcessor.Start
<| fun inbox ->
let rec loop () =
async {
let! (SetText text) = inbox.Receive()
form.Invoke(UpdateText(fun () -> form.SetText(text))) |> ignore
return! loop ()
}
loop ()
[<EntryPoint>]
let main argv =
async { form.ShowDialog() |> ignore } |> Async.Start
let rec loop () =
printf "Enter Text: "
match Console.ReadLine() with
| "exit" -> ()
| text -> agent.Post <| SetText text; loop()
loop ()
0

请注意,使用ShowDialog显示表单非常重要,否则承载表单的线程将返回到线程池,表单将变得没有响应。

相关内容

最新更新