Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从实例化对象读取属性是否线程安全?_C#_Thread Safety_Singleton - Fatal编程技术网

C# 从实例化对象读取属性是否线程安全?

C# 从实例化对象读取属性是否线程安全?,c#,thread-safety,singleton,C#,Thread Safety,Singleton,我是否可以安全地从多个线程中读取实例化单例的IsBusy布尔属性,而不会导致任何线程安全问题,或者我是否已经处于危险水域中?如果您已按以下方式定义属性IsBusy,那么您肯定会遇到线程安全问题: public bool IsBusy { get; set; } 这里最大的问题是可以在设置值之前检查并更改值。这意味着你有比赛条件。解决这一问题的一种方法是: // this is going to keep trying to lock until it succeeds, after which

我是否可以安全地从多个线程中读取实例化单例的
IsBusy
布尔属性,而不会导致任何线程安全问题,或者我是否已经处于危险水域中?

如果您已按以下方式定义属性
IsBusy
,那么您肯定会遇到线程安全问题:

public bool IsBusy { get; set; }
这里最大的问题是可以在设置值之前检查并更改值。这意味着你有比赛条件。解决这一问题的一种方法是:

// this is going to keep trying to lock until it succeeds, after which it 
//     will do whatever work needs done.
while (true) {
  bool lockObtained = false;
  lock (objectInstance) {
    if (!objectInstance.IsBusy) {
      lockObtained = true;
      objectInstance.IsBusy = true;
    }
  }

  if (lockObtained) {
    // good to go here

    // and don't forget to clear the IsBusy
    objectInstance.IsBusy = false;
    break;
  }
}

使用内置的.NET锁定机制来锁定对象,这样您就可以检查和设置,而不用担心中间的进程抢占。

如果您已经定义了属性<代码>忙> /代码>,那么您肯定可以有线程安全问题:

public bool IsBusy { get; set; }
这里最大的问题是可以在设置值之前检查并更改值。这意味着你有比赛条件。解决这一问题的一种方法是:

// this is going to keep trying to lock until it succeeds, after which it 
//     will do whatever work needs done.
while (true) {
  bool lockObtained = false;
  lock (objectInstance) {
    if (!objectInstance.IsBusy) {
      lockObtained = true;
      objectInstance.IsBusy = true;
    }
  }

  if (lockObtained) {
    // good to go here

    // and don't forget to clear the IsBusy
    objectInstance.IsBusy = false;
    break;
  }
}

使用内置的.NET锁定机制来锁定对象,这样您就可以检查和设置,而不用担心中间的进程抢占。

< P>除非有内存障碍,否则潜在的危险水域,如果值可以改变的话。 让我们把这个方程中的单态部分去掉,因为它不是特别相关。考虑这个简单的例子:

// Not safe!
public class BusyIndicator
{
    public bool IsBusy { get; set; }
}
现在,如果你有一条线,沿着以下线:

foo.IsBusy = true;
// do some work
foo.IsBusy = false;
另一个线程,仅在
IsBusy
设置为true后启动,它具有:

// Do some work
while (foo.IsBusy) { }
。。。那么第二条线可能会永远旋转。。。没有内存障碍来确保它“看到”第一个线程的更改

您可以使用锁定或使用
联锁
安全地执行此操作,例如:

// Safe (in terms of memory barriers)
public class BusyIndicator
{
    private int busy = 0;

    public bool IsBusy
    {
        get { return Interlocked.CompareExchange(ref busy, 0, 0) == 1; }
        set { Interlocked.Exchange(ref busy, value ? 1 : 0); }
    }
}

除非你有任何记忆障碍,否则你可能会陷入危险的境地,如果这个值可能会改变的话

让我们把这个方程中的单态部分去掉,因为它不是特别相关。考虑这个简单的例子:

// Not safe!
public class BusyIndicator
{
    public bool IsBusy { get; set; }
}
现在,如果你有一条线,沿着以下线:

foo.IsBusy = true;
// do some work
foo.IsBusy = false;
另一个线程,仅在
IsBusy
设置为true后启动,它具有:

// Do some work
while (foo.IsBusy) { }
。。。那么第二条线可能会永远旋转。。。没有内存障碍来确保它“看到”第一个线程的更改

您可以使用锁定或使用
联锁
安全地执行此操作,例如:

// Safe (in terms of memory barriers)
public class BusyIndicator
{
    private int busy = 0;

    public bool IsBusy
    {
        get { return Interlocked.CompareExchange(ref busy, 0, 0) == 1; }
        set { Interlocked.Exchange(ref busy, value ? 1 : 0); }
    }
}

取决于它是如何实现的。@Vlad:这取决于你所说的“线程安全”是什么意思。例如,如果valid可以由另一个线程更改,使用一个没有内存障碍的简单字段实现,并且您必须在另一个线程中看到更改,那么这是不安全的。@JeremyHolovacs您有4个不同的人要求您澄清问题,因为您的问题,信息严重不足,不需要真正负责。试图回答问题的人必须自己举出例子,试着猜测你在问什么,因为你在问题中没有提供足够的信息。在提出这个问题之前,你显然也没有对这个问题做过什么研究。“总而言之,我认为没有理由对这个问题投反对票,因为它没有展示研究成果,不清楚,不可回答,而且毫无用处。”杰里米霍洛瓦茨·乔恩猜到了你在做什么。他说你可能有问题。他不知道。他不知道,那是因为这个问题没有足够的信息来回答。他必须发明自己的问题,这样他才能回答,因为你的问题无法回答。如果你想知道你的问题遗漏了什么,从所有现有的评论开始,询问你更多的信息(顺便说一下,包括Jon)。这至少会给你一个开始的地方。@JeremyHolovacs不,答案不是否定的。回答是“也许,我们不知道,请提供更多信息。”即使Jon不能说“不”,他也只能说,“也许,但这里有一些其他情况,答案是否定的。”这取决于它的实现方式。@Vlad:这取决于你的意思“线程安全“。例如,如果valid可以由另一个线程更改,使用一个没有内存障碍的简单字段实现,并且您必须在另一个线程中看到更改,那么这是不安全的。@JeremyHolovacs您有4个不同的人要求您澄清问题,因为您的问题,信息严重不足,不需要真正负责。试图回答问题的人必须自己举出例子,试着猜测你在问什么,因为你在问题中没有提供足够的信息。在提出这个问题之前,你显然也没有对这个问题做过什么研究。“总而言之,我认为没有理由对这个问题投反对票,因为它没有展示研究成果,不清楚,不可回答,而且毫无用处。”杰里米霍洛瓦茨·乔恩猜到了你在做什么。他说你可能有问题。他不知道。他不知道,那是因为这个问题没有足够的信息来回答。他必须发明自己的问题,这样他才能回答,因为你的问题无法回答。如果你想知道你的问题遗漏了什么,从所有现有的评论开始,询问你更多的信息(顺便说一下,包括Jon)。这至少会给你一个开始的地方。@JeremyHolovacs不,答案不是否定的。回答是“也许,我们不知道,请提供更多信息。”即使是Jon也不能说“不”,他只能说,“也许,但在其他情况下,答案是否定的。”首先,你的财产没有阅读你的领域。第二,如果总是false,那么指示您是否忙又有什么意义呢?如果没有来自构造函数的初始值,这是非常无用的,而且它在语义上是一个常量,您只想避免编译器进行常量内联。@Servy我同意。我