winforms - 中止这个文件搜索线程是否安全?

标签 winforms multithreading thread-safety thread-abort

首先,代码:

lblFileNbr.Text = "?/?";
lblFileNbr.ToolTipText = "Searching for files...";
lock(_fileLock)
{
    _dirFiles = new string[0];
    _fileIndex = 0;
}
if(_fileThread != null && _fileThread.IsAlive)
{
    _fileThread.Abort();
}
_fileThread = new Thread(() =>
    {
        string dir = Path.GetDirectoryName(fileName) ?? ".";
        lock (_fileLock)
        {
            _dirFiles = GetImageFileExtensions().SelectMany(f => Directory.GetFiles(dir, f, _searchOption)).OrderBy(f => f).ToArray();
            _fileIndex = Array.IndexOf(_dirFiles, fileName);
        }
        int totalFileCount = Directory.GetFiles(dir, "*.*", _searchOption).Length;

        Invoke((MethodInvoker)delegate
        {
            lblFileNbr.Text = string.Format("{0}/{1}", NumberFormat(_fileIndex + 1), NumberFormat(_dirFiles.Length));
            lblFileNbr.ToolTipText = string.Format("{0} ({1} files ignored)", dir, NumberFormat(totalFileCount - _dirFiles.Length));
        });
    });
_fileThread.Start();

我正在构建一个小的图像查看程序。打开图像时,它会列出同一目录中的文件数。我注意到,当我在包含许多其他文件(比如 150K)的目录中打开图像时,构建文件列表需要几秒钟。因此,我将此任务委托(delegate)给另一个线程。

但是,如果您在完成搜索文件之前打开另一个图像,则旧计数不再相关,因此我将中止线程。

我正在锁定 _dirFiles_fileIndex因为我想添加一些左右键功能来在照片之间切换,所以我必须在其他地方访问它们(但在 UI 线程中)。

这安全吗?现在 C# 中处理线程的方法似乎有几十种,我只是想要一些简单的方法。
fileName是一个局部变量(这意味着它将被“复制”到匿名函数中,对吗?),和 _searchOption是只读的,所以我想这两个可以安全访问。

最佳答案

> Is it safe to abort this file-searching thread?



简短的回答是不!

中止线程几乎是不安全的,当您可能正在执行 native 代码时,此建议更适用。

如果您不能以足够快的速度合作退出(因为这是您对 Directory.GetFiles 的调用需要时间),您最好的选择是放弃线程:让它干净地完成但忽略其结果。

一如既往,我推荐阅读 Joe Albahari's free ebook

关于winforms - 中止这个文件搜索线程是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10970684/

相关文章:

multithreading - 这个读写器锁实现正确吗?

java - Statement.cancel() 及其线程安全保证

c# - 如何从 Newtonsoft.Json (C#) 访问嵌套的 JSON 对象?

c# - 间接访问需要 volatile 吗?

java - 等待所有阻塞队列元素取出后处理

c# - .NET:JsonMediaTypeFormatter 线程安全吗?

c - 从随机分布的粒子到规则网格的最佳并行通信

c# - 在 Windows 窗体应用程序表单中嵌入文件资源管理器实例

c# - 如何从某个网页复制所有文本并将其保存到记事本C#

c# - 如何更改按钮的大小