c# - 检查 null 线程安全吗?

标签 c# exception null thread-safety

我有一些代码在新线程上抛出异常,我需要在主线程上确认和处理这些异常。为实现这一点,我通过使用保存抛出异常的字段在线程之间共享状态。

我的问题是我是否需要在检查 null 时使用锁,就像我在下面的代码示例中所做的那样?

public class MyClass
{
    readonly object _exceptionLock = new object();
    Exception _exception;

    public MyClass()
    {
        Task.Run(() =>
        {
            while (CheckIsExceptionNull())
            {
                // This conditional will return true if 'something has gone wrong'.
                if(CheckIfMyCodeHasGoneWrong())
                {
                    lock(_exceptionLock)
                    {
                        _exception = new GoneWrongException();
                    }
                }
            }
        });
    }

    bool CheckIsExceptionNull() // Is this method actually necessary?
    {
        lock (_exceptionLock)
        {
            return _exception == null;
        }
    }

    // This method gets fired periodically on the Main Thread.
    void RethrowExceptionsOnMainThread()
    {
        if (!CheckIsExceptionNull())
        {
            lock (_exceptionLock)
            {
                throw _exception; // Does this throw need to be in a lock?
            }
        }
    }
}

此外,在主线程抛出异常时是否需要使用锁?

最佳答案

首先要注意的是你的代码不是线程安全的,因为你有一个线程竞争:你在一个不同的锁定区域检查 CheckIsExceptionNull 到你抛出的地方,但是:值可以在测试和 throw 之间切换

不保证字段访问是线程安全的。特别是,虽然引用不能被破坏(这是有保证的——引用的读取和写入是原子的),但保证不同的线程会看到最新的值,由于 CPU 缓存等。它不太可能真正咬你,但这是一般情况下线程问题的问题;p

就我个人而言,我可能只是让该字段可变,并使用一个本地的。例如:

var tmp = _exception;
if(tmp != null) throw tmp;

上面没有线程竞争。添加:

volatile Exception _exception;

确保该值未缓存在寄存器中(尽管从技术上讲这是一种副作用,而不是 volatile 的预期/记录效果)

关于c# - 检查 null 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30843413/

相关文章:

c# - 如何序列化嵌套的 JSON?

c# - 使用 Entity Framework 保存空字符串,用空格保存字符串?

c - C 中的读取访问冲突,试图找到源代码

java - 执行以下代码时,Author 类的yearofBirth 出现为空?

http - $http 每次启动后( ionic )在第一次调用时返回错误响应 NULL,但在随后的 http 发布后就可以了

java - 清除或设置 null 到 java 中的对象

c# - 将行添加到数据库时以大写形式保存值

c# - 运行时服务不再注入(inject) DNX 控制台应用程序 (RC1)

java - android - 如何获取发生异常的类和方法名称

excel - 如何在 Windows 7 pro excel 2010 中的多个显示器中打开两个 Excel 文件?