c# - 下面类线程安全吗?解释

标签 c# .net multithreading thread-safety

有人可以解释我是否可以调用下面的类“线程安全”吗?

据我所知,如果我们不破坏现有功能

,我们可以调用一些线程安全的东西

例子:

public class BackgroundWorker
{
    private readonly IDictionary<string, RunningTask> _runningTasks = new ConcurrentDictionary<string, RunningTask>();

    /// <summary>
    /// Executes async job for the specified key, only one at a time.
    /// </summary>
    /// <param name="key"></param>
    public void Enqueue(string key)
    {
        if (_runningTasks.ContainsKey(key))
        {
            _runningTasks[key].Repeat = true;
            return;
        }

        _runningTasks[key] = new RunningTask();

        ExecuteTask(key);
    }

    private void ExecuteTask(string key)
    {
        Task.Run(() =>
        {
            // Do something

            if (_runningTasks[key].Repeat)
            {
                _runningTasks[key].Repeat = false;
                ExecuteTask(key);
                return;
            }

            _runningTasks.Remove(key);
        });
    }

    private class RunningTask
    {
        /// <summary>
        /// Flag to repeat a task after completion.
        /// </summary>
        public bool Repeat { get; set; }
    }
}

最佳答案

我不这么认为,因为 _runningTasks 是共享对象,而您的方法 Enqueue 正在写入此共享对象。例如,当一个线程已经执行了行号 y 时,另一个线程可能会将行号 x 中的条件检查评估为真——这可能不是故意的。

public void Enqueue(string key)
{
    if (_runningTasks.ContainsKey(key)) /*say line no : x */
    {
        _runningTasks[key].Repeat = true;
        return;
    }

    _runningTasks[key] = new RunningTask(); /*say line no:y*/

    ExecuteTask(key);
}

使用 ConcurrentDictionary 只会确保没有两个线程可以同时读取/写入字典。

第二点:

As far as I know, we can call something thread safe if we are not breaking existing functionality

不,这不是线程安全的定义(可以说是多线程环境中的理想结果之一)我建议阅读 this post而不是官方的意思。

关于c# - 下面类线程安全吗?解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49092969/

相关文章:

c# - Windows Phone 8.1 应用程序中的后台线程

java - 为什么我应该使用 NIO(或像 netty 这样的框架)而不是 java 执行器?

c# - 如何比较日期时间的时间部分

c# - 如何将 IntPtr 传递给非托管 C++ CLR 托管代码的方法?

.net - 为什么 InvalidEnumArgumentException 在 Silverlight 4 中已过时?

c# - 寻找如何重构我的算法的想法

c++ - _beginthreadex 静态成员函数

c# - 在 service .net core 中获取 appsettings.json 值

c# - 如何在未处理的异常后继续运行?

c# - 具有 BoundedCapacity 的 BufferBlock 和 ActionBlock 不使用最大 DOP