Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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/6/multithreading/4.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#_Multithreading_Interface - Fatal编程技术网

在C#中在何处使用同步方法:接口还是实现?

在C#中在何处使用同步方法:接口还是实现?,c#,multithreading,interface,C#,Multithreading,Interface,我们有一个用于记录器应用程序的接口,它可以有不同的实现。作为记录器,实现的对象可以在多个模块之间共享,因此需要同步 我正在使用此代码使方法同步:[MethodImpl(MethodImplOptions.synchronized)] 我的问题是:如果我在接口中使用此注释,它会使所有实现同步吗?或者,我需要将此注释放在特定的实现中吗?它对接口没有好处,因为MethodImplAttribute本身标记为AttributeUsageAttribute.Inherited=false 但这是一个反模式

我们有一个用于记录器应用程序的接口,它可以有不同的实现。作为记录器,实现的对象可以在多个模块之间共享,因此需要同步

我正在使用此代码使方法同步:
[MethodImpl(MethodImplOptions.synchronized)]


我的问题是:如果我在接口中使用此注释,它会使所有实现同步吗?或者,我需要将此注释放在特定的实现中吗?

它对接口没有好处,因为
MethodImplAttribute
本身标记为
AttributeUsageAttribute.Inherited=false

但这是一个反模式,无论如何,文件说

对于公共类型,不建议使用
Synchronized
标志锁定实例或类型,因为您自己的代码以外的代码可以锁定公共类型和实例。这可能会导致死锁或其他同步问题

相反,实现应该锁定(如果不是内部线程安全的话)类的
私有
对象的实例


声明式同步的问题是众所周知的——它会导致锁顺序反转——因此反对使用它的建议是普遍的。

它对接口没有好处,因为
MethodImplAttribute
本身被标记为
AttributeUsageAttribute.Inherited=false

但这是一个反模式,无论如何,文件说

对于公共类型,不建议使用
Synchronized
标志锁定实例或类型,因为您自己的代码以外的代码可以锁定公共类型和实例。这可能会导致死锁或其他同步问题

相反,实现应该锁定(如果不是内部线程安全的话)类的
私有
对象的实例

声明式同步的问题是众所周知的——它会导致锁顺序反转——因此反对使用它的建议是普遍的。

[MethodImpl(methodimpoptions.Synchronized)]
是一个老生常谈的想法,但结果却是非常糟糕的

如果您查看上的文档,您将看到

静态方法锁定类型,而实例方法锁定 实例。

因此,由于您正在使用一个接口,并且正如已经指出的那样,
MethodImplAttribute
被标记为
AttributeUsageAttribute.Inherited=false
,因此您的实现将锁定到
这个
,这被认为是一个非常糟糕的模式,最终会导致死锁。

是一个老生常谈的想法,但结果却非常糟糕

如果您查看上的文档,您将看到

静态方法锁定类型,而实例方法锁定 实例。


因此,由于您使用的是一个接口,并且正如已经指出的那样,
MethodImplAttribute
标记为
AttributeUsageAttribute.Inherited=false
,因此您的实现将锁定到
这个
,这被认为是一个非常糟糕的模式,最终会导致死锁。

感谢您的澄清在继承标志上。但不确定是否存在死锁,因为在使用嵌套同步时会发生死锁。如果我提供了一个同步方法,它应该如何创建死锁,除非启用,直到我从它调用其他同步方法为止?@AmberBeriwal:在持有锁的情况下调用同步方法就足以触发死锁死锁如果另一个线程以不同的顺序获取锁,即使同步方法不调用更多的同步方法,也可能发生死锁。因为声明性同步在对象上工作,所以您无法控制另一个线程是否获取相同的锁。这就是为什么锁定私有对象可以解决问题——您可以re没有其他代码使用相同的锁。@Amberberival:现在应该清楚,能够标记接口并自动获得所有实现者的行为将是可怕的——实现者不知道如何避免嵌套锁,而使用并发集合实现的实现将为不必要的锁支付费用ng.完全同意第二点。我仍然怀疑第一点。虽然获取锁的对象不同。但是,两个同步方法和两个具有完全同步块的非同步方法应该是相同的。我会在做出任何结论之前进行一些实验。谢谢。感谢您的澄清在继承标志上。但不确定是否存在死锁,因为在使用嵌套同步时会发生死锁。如果我提供了一个同步方法,它应该如何创建死锁,除非启用,直到我从它调用其他同步方法为止?@AmberBeriwal:在持有锁的情况下调用同步方法就足以触发死锁死锁如果另一个线程以不同的顺序获取锁,即使同步方法不调用更多的同步方法,也可能发生死锁。因为声明性同步在对象上工作,所以您无法控制另一个线程是否获取相同的锁。这就是为什么锁定私有对象可以解决问题——您可以re没有其他代码使用相同的锁。@Amberberival:现在应该清楚,能够标记接口并自动获得所有实现者的行为将是可怕的——实现者不知道如何避免嵌套锁,而使用并发集合实现的实现将为不必要的锁支付费用完全同意第二点。第一点对我来说仍然是可疑的。尽管目标