c# - 在 WPF 中实现 Console.ReadLine?

标签 c# wpf multithreading

我正在尝试使用 C# WPF 创建一个应用程序来模拟 Windows 的命令提示符,但具有更多的灵 active 和输出选项(如显示图像或表单)。我最近一直在尝试模拟 Console.ReadLine()。我需要保持 GUI 完全响应,允许用户键入输入。同时,我需要能够从同一方法返回答案。

我已经尝试通过使用事件来解决这个问题,但我不知道如何以不返回 void 的方式使用它们。我查看了 async/awaitquestion about it ,但不太清楚如何使用该信息。我考虑了一个事件驱动的解决方案,其中结果将存储在所有输入的永久列表变量中,我可以读取最后一个以获取最新输入,但我认为它不够好模拟。

我计划在应用程序启动后立即在主线程中创建控制台 GUI。但是,我将在另一个线程中使用它的逻辑,这将是我的代码的核心(我知道这不是一种专业的编程方式,但毕竟这是个人项目/学习经验。)然后,我想使用某种自定义 ReadLine() 方法等待用户提交文本,然后返回它。如果这是可能的,如何在 WPF 中完成?

最佳答案

以下快速而粗糙的代码应该让您了解如何实现您想要的:

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        var console = new MyConsole();
        this.Content = console.Gui;
        Task.Factory.StartNew(() => {
            var read = console.ReadLine();
            console.WriteLine(read);
        });
    }
}

public class MyConsole {
    private readonly ManualResetEvent _readLineSignal;
    private string _lastLine;        
    public MyConsole() {
        _readLineSignal = new ManualResetEvent(false);
        Gui = new TextBox();
        Gui.AcceptsReturn = true;
        Gui.KeyUp += OnKeyUp;
    }

    private void OnKeyUp(object sender, KeyEventArgs e) {
        // this is always fired on UI thread
        if (e.Key == Key.Enter) {
            // quick and dirty, but that is not relevant to your question
            _lastLine = Gui.Text.Split(new string[] { "\r\n"}, StringSplitOptions.RemoveEmptyEntries).Last();
            // now, when you detected that user typed a line, set signal
            _readLineSignal.Set();
        }
    }        

    public TextBox Gui { get; private set;}

    public string ReadLine() {
        // that should always be called from non-ui thread
        if (Gui.Dispatcher.CheckAccess())
            throw new  Exception("Cannot be called on UI thread");
        // reset signal
        _readLineSignal.Reset();
        // wait until signal is set. This call is blocking, but since we are on non-ui thread - there is no problem with that
        _readLineSignal.WaitOne();
        // we got signalled - return line user typed.
        return _lastLine;
    }

    public void WriteLine(string line) {
        if (!Gui.Dispatcher.CheckAccess()) {
            Gui.Dispatcher.Invoke(new Action(() => WriteLine(line)));
            return;
        }

        Gui.Text += line + Environment.NewLine;
    }
}

关于c# - 在 WPF 中实现 Console.ReadLine?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32555709/

相关文章:

c# - Entity Framework 中一个或多个实体对可空 bool 属性的验证失败

c# - 将字符串转换为十六进制字符串的 C# 惯用方法是什么?

c# - "Unsupported overload used for query operator ' 哪里'

javascript - linq 在 javascript 中工作吗

c# - 将 Unity 中的 XAML (WPF) 应用与 MixedRealityToolkit 相结合

wpf - VS Wpf Designer如何实例化和限制执行VIewModel代码?

c# - WPF 绑定(bind)可见性

java - 多线程处理中静态成员的意外行为

boost - boost threadpool-文档和示例

java - 等待线程不恢复