具有停止/暂停/继续功能的多线程

时间:2015-10-26 00:36:38

标签: c# .net multithreading

我正在编写一个程序来查找特定文件夹中的所有重复文件。

我的想法是将所有文件名收集到string[]。然后运行多个线程,这些线程散列每个string []元素文件(按内容散列)并检查散列是否已经在字典中查找重复项。

我用开始按钮初始化我的搜索:

    //Start button:
    private void btnStart_Click(object sender, EventArgs e)
    {
            Search.initialize(this.labelPath.Text, this.textResultsFile.Text);
    }

    //My run method
    public void run(string basePath, string resultFile)
    {
        //string[] contains all file paths
        string[] filePaths = Directory.GetFiles(@basePath, "*", SearchOption.AllDirectories);

        HashingCompletedCallback callback = new HashingCompletedCallback(CheckDuplicate);
        Multi multi = new Multi(string[0], callback);
        Thread T1 = new Thread(new ThreadStart(multi.HashFile));
        T1.Start();
    }

所以在这种情况下,我正在使用string[0],这是路径列表中的第一个路径(例如:C:/BasePath/first.txt'),哈希文件,并且callback检查是否存在哈希字典,如果是,则找到重复,否则我只是将哈希添加到库中。

所以我现在面临的一些问题是:

  1. 如何在此类搜索中实现停止/继续和重启按钮?我已经使用Windows.Forms创建了这些按钮,但我不确定如何控制它们而不会因用户界面锁定而失败。例如,如果我开始foreach string[] as element - >我的用户界面冻结,无法执行任何操作。

  2. 目前我编写了我的程序,所以我可以使用一个工作线程。如何自动创建更多线程并让它们参与搜索?在这种情况下,我想我必须把锁放入我的回调中,所以我的字典一次只能由一个线程检查和编写。在这可以我只是锁定我的方法函数或整个类将被锁定?

  3. 顺便说一句:我确实读过:how to pause/resume a thread但不确定如何使用它。

1 个答案:

答案 0 :(得分:1)

  

如何在此类搜索中实现停止/继续和重启按钮?

您可以使用ManualResetEvent让UI线程控制工作线程是运行还是暂停。工作线程将在处理下一个文件之前调用WaitOne。

  

ManualResetEvent的功能与普通门类似。调用Set打开门,允许任意数量的调用WaitOne的线程通过。调用重置会关闭门。在关闭的门上调用WaitOne的线程将阻塞;当下一个门打开时,它们将立即释放。

Source

  

目前我编写了我的程序,所以我可以使用一个工作线程。如何自动创建更多线程并让它们参与搜索?在这种情况下,我想我必须把锁放入我的回调中,所以我的字典只能由一个线程一次检查和编写。

考虑一个ConcurrentDictionary而不是一个字典,因为它被设计为线程安全的。

这些天我会使用Task而不是Thread。假设你坚持使用Thread,你可以做类似的事情。

Thread T1 = new Thread(new ThreadStart(multi.HashFile));
T1.Start();
// Repeat for T2, T3, etc as desired.
T1.Join();
// Repeat for T2, T3, etc.