我正在编写一个程序来查找特定文件夹中的所有重复文件。
我的想法是将所有文件名收集到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
检查是否存在哈希字典,如果是,则找到重复,否则我只是将哈希添加到库中。
所以我现在面临的一些问题是:
如何在此类搜索中实现停止/继续和重启按钮?我已经使用Windows.Forms创建了这些按钮,但我不确定如何控制它们而不会因用户界面锁定而失败。例如,如果我开始foreach
string[] as element
- >我的用户界面冻结,无法执行任何操作。
目前我编写了我的程序,所以我可以使用一个工作线程。如何自动创建更多线程并让它们参与搜索?在这种情况下,我想我必须把锁放入我的回调中,所以我的字典一次只能由一个线程检查和编写。在这可以我只是锁定我的方法函数或整个类将被锁定?
顺便说一句:我确实读过:how to pause/resume a thread但不确定如何使用它。
答案 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.