【问题标题】:C# Call function in while loop every X seconds without blocking loopC#在while循环中每X秒调用一次函数而不阻塞循环
【发布时间】:2018-03-15 11:10:53
【问题描述】:

我有一个 C# 程序,我正在使用 while 循环从文件中读取行。我希望能够每 5 秒左右显示一次行号,而不会减慢 while 循环,这样用户就可以看到它们有多远。任何想法如何做到这一点?

代码

    try
    {
        // Create an instance of StreamReader to read from a file.
        // The using statement also closes the StreamReader.
        Stopwatch sw = Stopwatch.StartNew();
        using (StreamReader sr = new StreamReader(@"C:\wamp64\www\brute-force\files\antipublic.txt"))
        {
            String line;
            int lines = 0;
            // Read and display lines from the file until the end of 
            // the file is reached.
            using (System.IO.StreamWriter file = new System.IO.StreamWriter("C:/users/morgan/desktop/hash_table.txt"))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    file.WriteLine(CreateMD5(line)+':'+line);
                    lines++;
                }
            }
        }

        sw.Stop();
        Console.WriteLine("Time taken: {0}s", sw.Elapsed.TotalSeconds);
        Console.ReadLine();
    }
    catch (Exception e)
    {
        // Let the user know what went wrong.
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
    }
}

【问题讨论】:

  • 在后台线程运行文件读取代码并向UI线程发送通知。
  • 在您的 while 循环工作中不能在 lines++ 之后使用简单的 if (sw.Elapsed.TotalSeconds % 5 == 0) Console.WriteLine(lines + " lines read so far..."); 吗?
  • Simple Console.WriteLine 每 5 秒不会显着减慢循环速度。或者你可以使用 Task.Run

标签: c# while-loop nonblocking


【解决方案1】:

您可以使用BackgroundWorker 类来实现这一点。只需查看有关如何初始化类的 MSDN 示例。

您可以使用这样的 ReportProgress 调用为 BackgroundWorker 创建一个“DoWork”方法:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;

    Stopwatch sw = Stopwatch.StartNew();
    using (StreamReader sr = new StreamReader(@"path"))
    {
        String line;
        int lines = 0;

        using (System.IO.StreamWriter file = new System.IO.StreamWriter("path"))
        {
            while ((line = sr.ReadLine()) != null)
            {
                file.WriteLine(CreateMD5(line)+':'+line);
                worker.ReportProgress(lines++);
            }
        }
    }
}

要显示进度,您只需在 ProgressChanged 事件中使用 Console.WriteLine()。

【讨论】:

  • MSDN 文档指出 ProgressChanged 事件处理程序在创建 BackgroundWorker 的线程上执行。 DoWork 应该在与创建的 BackgroundWorker 实例不同的线程上运行。
猜你喜欢
  • 2022-11-20
  • 2021-12-30
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 2016-04-21
相关资源
最近更新 更多