如何使用 C# 将同一个实例共享给多个线程中的所有派生 类?
How can I share the same instance to all derived classes in multiple threads with C#?
我在 C# 中使用 命令模式。
有一个 class 包含一些名为 RequiredData
.
的属性
public class RequiredData
{
public Class1 class1 { get; set; }
public int value1 {get; set;}
}
有一个抽象 class BaseCommand
并且有一些派生的 class 像 command1 , command2 etc
.
abstract class BaseCommand : ICommand { }
这些命令会执行一些操作,例如:
command1.Execute();
command2.Execute();
我希望在整个过程中有一个共享的 RequiredData 对象,它可以在所有命令中更新和使用。
例如:
在 command1 Execute 方法中访问 value1,如:
RequiredData.Value1 = 5
然后在 command2 Execute 方法中使这个值像
var k = RequiredData.Value1 //and be 5..
or RequiredData.Class1.something = "something"
我在基地试过这个 class:
abstract class BaseCommand : ICommand
{
//or protected and not private...
public static RequiredData RequiredData = new RequiredData();
}
这是线程安全的吗?
线程安全解决方案需要进行哪些更改?
您可以使用多种方法解决此问题。
- 将共享实例传递给构造函数
- 单例 pattern/static 可以提供帮助,但限制更多。
提醒一下,如果你在不同的线程上使用class,你需要注意线程安全。
通常我会避免使用可以被多个线程 readed/writed 的静态对象。我建议你尝试摆脱这个。
但是...您需要确定 object/reference 类型无法从外部访问。
喜欢:
// you could create the locking in this class, but the class1 property is a
// reference type, so just locking in the property is not enought, it
// goes wrong when the Class1 has properties itself. (then these will be
// altered outside the lock..
// I choose to wrap the whole object and only returning value types
public class RequiredData
{
public Class1 class1 { get; set; }
public int value1 {get; set;}
}
abstract class BaseCommand : ICommand
{
// protected.. should not be accessable from the outside..!
protected static RequiredData RequiredData = new RequiredData();
public int GetValue()
{
lock(RequiredData)
return RequiredData.value1;
}
public void SetValue(int value)
{
lock(RequiredData)
RequiredData.value1 = value;
}
// or you could wrap this in a property
public int Value
{
get { return lock(RequiredData) RequiredData.value1; }
set { lock(RequiredData) RequiredData.value1 = value; }
}
public string GetSomething()
{
// try to avoid returning reference types, but the can be referenced from outside the object.
lock(RequiredData)
return RequiredData.Class1.something;
}
}
所以锁定应该在 BaseCommand
内。而 BaseCommand
应该负责与 RequiredData 进行通信。 (因此没有其他对象可以引用 RequiredData)
就像我说的:多线程/静态read/writer = 玩火。
如果你有很多 readers/writers 你应该看看 ReaderWriterLock(Slim)。因为多个线程可以同时读取并且只有一个写入器处于活动状态。
我在 C# 中使用 命令模式。
有一个 class 包含一些名为 RequiredData
.
public class RequiredData
{
public Class1 class1 { get; set; }
public int value1 {get; set;}
}
有一个抽象 class BaseCommand
并且有一些派生的 class 像 command1 , command2 etc
.
abstract class BaseCommand : ICommand { }
这些命令会执行一些操作,例如:
command1.Execute();
command2.Execute();
我希望在整个过程中有一个共享的 RequiredData 对象,它可以在所有命令中更新和使用。 例如:
在 command1 Execute 方法中访问 value1,如:
RequiredData.Value1 = 5
然后在 command2 Execute 方法中使这个值像
var k = RequiredData.Value1 //and be 5..
or RequiredData.Class1.something = "something"
我在基地试过这个 class:
abstract class BaseCommand : ICommand
{
//or protected and not private...
public static RequiredData RequiredData = new RequiredData();
}
这是线程安全的吗?
线程安全解决方案需要进行哪些更改?
您可以使用多种方法解决此问题。
- 将共享实例传递给构造函数
- 单例 pattern/static 可以提供帮助,但限制更多。
提醒一下,如果你在不同的线程上使用class,你需要注意线程安全。
通常我会避免使用可以被多个线程 readed/writed 的静态对象。我建议你尝试摆脱这个。
但是...您需要确定 object/reference 类型无法从外部访问。
喜欢:
// you could create the locking in this class, but the class1 property is a
// reference type, so just locking in the property is not enought, it
// goes wrong when the Class1 has properties itself. (then these will be
// altered outside the lock..
// I choose to wrap the whole object and only returning value types
public class RequiredData
{
public Class1 class1 { get; set; }
public int value1 {get; set;}
}
abstract class BaseCommand : ICommand
{
// protected.. should not be accessable from the outside..!
protected static RequiredData RequiredData = new RequiredData();
public int GetValue()
{
lock(RequiredData)
return RequiredData.value1;
}
public void SetValue(int value)
{
lock(RequiredData)
RequiredData.value1 = value;
}
// or you could wrap this in a property
public int Value
{
get { return lock(RequiredData) RequiredData.value1; }
set { lock(RequiredData) RequiredData.value1 = value; }
}
public string GetSomething()
{
// try to avoid returning reference types, but the can be referenced from outside the object.
lock(RequiredData)
return RequiredData.Class1.something;
}
}
所以锁定应该在 BaseCommand
内。而 BaseCommand
应该负责与 RequiredData 进行通信。 (因此没有其他对象可以引用 RequiredData)
就像我说的:多线程/静态read/writer = 玩火。
如果你有很多 readers/writers 你应该看看 ReaderWriterLock(Slim)。因为多个线程可以同时读取并且只有一个写入器处于活动状态。