我正在尝试在.Net中构建一个starcraft2 AI,我想显示一个包含一些实时特征地图数据的窗口。AI从控制台应用程序运行,我想让它保持这种方式。我想让我的代码输出一些位图数据来显示在窗口中,因为AI是实时完成它的事情的。但是,在this answer中,从控制台应用程序运行窗体似乎会阻塞控制台线程。
如何从控制台应用程序运行窗体,并定期向其传递位图?我是用F#做的,但我很高兴看到基于C#或VB.Net的答案,因为我可以根据需要进行翻译。
我不想尝试将它作为Windows应用程序运行来显示表单,然后让我的AI从那里运行,因为在某些时候,我可能想在梯子上与我的AI竞争,我不确定windows forms应用程序是否会被支持。
我想我可以让我的控制台应用程序通过零mq或其他方式发布数据,然后恰好侦听的任何进程都可以显示数据,但对于一个简单的需求来说,这似乎有点复杂。如果没有更好(更容易)的解决方案,我会认为这是答案。
发布于 2018-07-27 22:32:11
下面是一个使用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
显示表单非常重要,否则托管表单的线程将返回线程池,表单将变得无响应。
https://stackoverflow.com/questions/51559754
复制相似问题