【问题标题】:StreamReader posting in an Textbox with delayStreamReader 在文本框中延迟发布
【发布时间】:2015-09-08 20:00:46
【问题描述】:
StreamReader file = new StreamReader(@"C:\Users\User\Documents\Files.txt");

while ((line = file.ReadLine()) != null)
{
    richTextBox1.Text += Environment.NewLine + "Copying: " + line;
    counter++;
}

我有这段代码来读取其中包含多个路径的文本文件。我想要做的是将它们发布到我到目前为止得到的文本框中,但我的问题是我可以在流阅读器要发布的每一行之间延迟 1 秒吗?

【问题讨论】:

  • 不好意思忘了是windows窗体
  • Thread.Sleep(1000); ...?
  • @sab669 为什么建议一些只会导致“为什么我的 UI 被冻结”的内容?
  • 我试过线程睡眠,但它只是说线程在那个上下文中不存在
  • stackoverflow.com/questions/24720319/timer-in-winforms 有基于计时器和异步/等待的解决方案。

标签: c# winforms textbox streamreader


【解决方案1】:

类似的东西:

System.Threading.ThreadPool.QueueUserWorkItem((obj) =>
{
    StreamReader file = new StreamReader(@"C:\Users\User\Documents\Files.txt");
    string line;
    int counter = 0;
    while ((line = file.ReadLine()) != null)
    {
        this.Invoke((Action)(() =>
            {
                richTextBox1.Text += Environment.NewLine + "Copying: " + line;
            }));
        System.Threading.Thread.Sleep(1000);
        counter++;
    }
});

或者,如上面 cmets 中建议的那样,也可以使用 BackgroundWorker

Documentation

【讨论】:

  • 我稍后会试试这个,还有其他工作要做。到时候我会给你一些反馈
【解决方案2】:

1) 使用System.Windows.Forms.Timer

实现一个以用户定义的时间间隔引发事件的计时器。此计时器针对在 Windows 窗体应用程序中的使用进行了优化,并且必须在窗口中使用。

2) 读取队列中的所有行。

Queue<string> lines = new Queue<string>( File.ReadAllLines( @"Path" ) );

3) 使用定时器事件读取列表中的每一行。

private void Timer_Tick( object sender, EventArgs e )
    {
        if ( lines.Count > 0 )
        {
            richTextBox1.Text += Environment.NewLine + "Copying: " + lines.Dequeue();
            counter++;
        }
    }

检查空的Queue.Dequeue Methodlines.Count &gt; 0 或其他,当它变为真时停止计时器)

【讨论】:

    【解决方案3】:

    您可以使用 System.Threading 类调用:Thread.Sleep(1000); 每次循环迭代一次。

    有关 System.Threading 类的更多信息,请访问MSDN

    编辑:

    如下所述,使用 Thread.Sleep 会导致 UI 在 Sleep 方法期间锁定。作为替代方案,您可能想尝试BackgroundWorker class.

    以下 sn-p 假设您想通过单击按钮触发上面的代码(从问题中不清楚这是否真的是这种情况)。

    private void startAsyncButton_Click(object sender, EventArgs e)
    {
       if(backgroundWorkerA.IsBusy != true)
       {
          //start the Async Thread
          backgroundWorkerA.RunWorkerAsync();
       }
    }
    
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
       StreamReader file = new StreamReader(@"C:\Users\User\Documents\Files.txt");
    
       while ((line = file.ReadLine()) != null)
       {
           richTextBox1.Text += Environment.NewLine + "Copying: " + line;
           counter++;
           Thread.Sleep(1000);
       }
    }
    

    在这里,您只是创建了一个工作线程来执行(相对)耗时的任务,而不会占用您的 GUI。

    【讨论】:

    • 正如 Alexei 指出的那样,这将导致 UI 一次冻结一秒钟。如果您不想要这样的功能,我建议您研究 BackgroundWorker 类。
    • 不应该在 UI 线程上使用 Thread.Sleep。在非 UI 线程上执行此操作需要的代码比本文中显示的要多得多。
    • 是的,刚刚发现我的 ui 死了
    • @Ayres 参见上面的编辑答案,包括 BackgroundWorker 信息。
    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2015-09-14
    • 2014-05-14
    相关资源
    最近更新 更多