代码之家  ›  专栏  ›  技术社区  ›  Chechy Levas

如何在新窗口中使用.NET(c/f)显示来自控制台应用程序的更改(动画)图像,而不阻塞控制台?

  •  0
  • Chechy Levas  · 技术社区  · 6 年前

    我正在尝试在.NET中构建Starcraft2人工智能,我想显示一个带有一些实时功能图数据的窗口。人工智能从一个控制台应用程序运行,我希望保持这种方式。我想让我的代码输出一些位图数据显示在一个窗口中,就像人工智能实时地做它的事情一样。然而,从 this answer ,似乎从控制台应用程序运行表单会阻塞控制台线程。

    如何从控制台应用程序运行表单并定期向其传递位图?我在f中做这个,但是我很高兴看到基于c或vb.net的答案,因为我可以根据需要翻译它。

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

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Aaron M. Eshbach    6 年前

    下面是一个使用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 ,否则承载表单的线程将返回线程池,表单将变得无响应。