c# - 使用 RichTextBox 在文本追加中创建延迟

标签 c# richtextbox delay

我正在尝试使用 C# 创建一个逼真的控制台类型游戏,我需要它做的是附加如下文本:

hi
hello
awesome
nice

但我希望它这样做:

hi
(2 second pause)
hello
(4 second pause)
awesome
(1 second pause)
nice

我已经尝试过这个:

delegate void _pause(int time);
    void pause(int time)
    {
        if (txtInput.Text != "")
        {
            txtInput.Clear();
        }

        Stopwatch s = new Stopwatch();
        s.Start();
        while (s.Elapsed < TimeSpan.FromSeconds(time))
        {
        }
        s.Stop();
        return;
    }

然后我可以这样调用它 Invoke(new _pause(pause),3); 但这基本上会卡住线程!所以无论如何它都会立即粘贴,只是之前有延迟 粘贴的蒙太奇!

我怎样才能做一个像我所描述的平滑的延迟类型系统?

最佳答案

您应该避免忙等待,而应使用计时器,例如 Task.Delay .

一种可能的方法是利用 C# 4.5 的新异步功能:

async void converse() {
    txtInput.Text = "hi\n";
    await Task.Delay(2000);
    txtInput.Append("hello\n");
    await Task.Delay(4000);
    txtInput.Append("awesome\n");
    await Task.Delay(1000);
    txtInput.Append("nice\n");
}

通过使用异步语法,您可以指示机器与其他代码交错运行您的代码 - 例如,这样它仍然可以同时进行屏幕更新。它会自动返回到相同的 SynchronizationContext,因此在您的情况下,自从您在 GUI 线程上启动以来,您将继续使用它;这很重要,因为只有该线程可能会更改您的文本框。

总结一下为什么要这样做:

  • 您可以避免占用 CPU 的忙于等待,从而浪费能源。
  • 您可以避免阻塞 GUI 线程,以便您的更新按时出现(例如,与 CPU 占用不同,也与 Thread.Sleep 不同)
  • 您无需特别担心线程调度,因为异步功能会为您做到这一点。

如果您需要支持.NET 2.0,您可能需要查看 Windows 窗体 Timer 。简而言之,这公开了您可以在延迟后触发的事件处理程序。然而,正如 MSDN 页面上的示例所示,它并不那么容易使用,并且需要更多的手动编排。

此外,您可以使用线程。如果这样做,您有责任确保线程安全:您不能在 GUI 线程以外的任何线程上执行 txtInput.Append:

void startConversation() {
    (new Thread(converse) {IsBackground = true}).Start();
}
void converse() { //called a different thread
    UI(() => txtInput.Text = "hi\n");
    Thread.Sleep(2000);
    UI(() => txtInput.Append("hello\n"));
    Thread.Sleep(4000);
    UI(() => txtInput.Append("awesome\n"));
    Thread.Sleep(1000);
    UI(() => txtInput.Append("nice\n"));
}
void UI(Action action) { this.BeginInvoke(action); }

此模型几乎与异步模型一样简单。两个陷阱是,您应该避免忙等待(使用 Thread.Sleep),并且必须确保对所有影响 UI 的代码正确使用 BeginInvoke。它甚至可能比async稍快。但是,线程具有相当大的开销(主要是在内存方面),因此该解决方案无法扩展到大量延迟交互。

摘要

  • 如果可以的话,使用异步
  • 或者,使用 Windows 窗体 Timer,这很麻烦。
  • 或者使用后台线程 - 但要注意扩展问题和忙于等待。

关于c# - 使用 RichTextBox 在文本追加中创建延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14998679/

相关文章:

c# - 在 .Net 中实现优先级数组集合的最快(插入速度)方法是什么?

c# - MVVM - 单击按钮时在哪里调用函数?

c# - 我怎么知道用户何时可以使用强制滚动条滚动 RichTextBox

python - 是否可以使用Python提高Raspberry Pi上ADXL345的采样率?

javascript - 使用nodejs在一定时间后运行函数/代码

c# - FxCop:异步方法的抑制消息

c# - 在 VB/C# .NET 中使用 DataGridView 数据填充数据表

c# - 将 RichTextBox FlowDocument 保存到图像

c# - 在 Richtextbox 控件中将超链接显示为纯文本

java - Solr 文档删除延迟