C# 对象()的新实例

C# 对象()的新实例,c#,.net,C#,.net,我遇到了对象构造函数的这个定义(元数据来自mscorlib.dll) 我不明白什么是ConstrainedExecution(Cer.MayFail)有人能给我举个例子吗 我遇到了这个代码,也告诉我这样写是否正确 public class MyClass { private static object instanceLock = new object(); private void Func() { bool instanceLockTaken = f

我遇到了
对象
构造函数的这个定义(元数据来自
mscorlib.dll

我不明白什么是
ConstrainedExecution
Cer.MayFail
)有人能给我举个例子吗

我遇到了这个代码,也告诉我这样写是否正确

public class MyClass
{
    private static object instanceLock = new object();

    private void Func()
    {
        bool instanceLockTaken = false;

        Monitor.TryEnter(instanceLock, ref instanceLockTaken);
        //...
        Monitor.Exit(instanceLock);
    }
}

约束执行是您试图通过锁定线程来实现的

发件人:

Cer值MayFail用于在遇到以下情况时发出信号: 异步异常时,代码可能无法在预期的时间内完成 时尚因为线程中止被延迟了超过限制 执行区域,这实际上意味着您的代码正在执行某些操作 这可能会导致分配内存或导致堆栈 溢流更重要的是,这意味着你必须采取可能的措施 调用此方法时要考虑失败

在您的情况下,因为对象是静态的,并且只创建一次,所以这不会是一个问题

Monitor.TryEnter
即使未获取锁,也会立即返回。它有一个布尔值,您没有检查它,类似这样的东西可以工作:

Monitor.TryEnter(instanceLock, ref instanceLockTaken);

  if (instanceLockTaken) 
  {
    // Do stuff here

    Monitor.Exit(instanceLock);
  }
但是,这段代码意味着,
if{}
块不会每次都执行,如果您想在每个线程上获得锁,则需要执行如下操作:

lock(instanceLock)
{
  // Do stuff here
}
    bool instanceLockTaken = false;
    try
    {
      Monitor.Enter(instanceLock, ref instanceLockTaken);

    //...
    }
    finally
    {
      if (instanceLockTaken) 
      {
         Monitor.Exit(instanceLock);
      }
    }
这意味着一次只有一个线程可以运行
lock{}
语句的内容,并且每次都会执行lock语句的内容

在旁注中,您还可以将要锁定的对象设置为只读:


private static readonly object instanceLock=new object()

Cer.Mayfail关键字表示如果标记的方法引发异常,则数据可能处于无效状态;对象以前的状态将不会恢复

一般来说,这里有两个问题

1) 可靠性契约是CLR团队用于支持受限执行区域的工具。这是一个高级主题,但简单地说,构造描述了一个函数(或构造函数)是否会失败,如果是,会产生什么影响(无影响、appDomain影响、流程影响、整个机器崩溃等)

2) 您的代码片段不正确。如果不想进一步检查,为什么要保存InstanceLockTake?此外,如果在获取锁和释放锁之间发生异常,则会泄漏锁。 考虑使用<代码>锁定> /Cord>语句,这是类似于此的语法糖:

lock(instanceLock)
{
  // Do stuff here
}
    bool instanceLockTaken = false;
    try
    {
      Monitor.Enter(instanceLock, ref instanceLockTaken);

    //...
    }
    finally
    {
      if (instanceLockTaken) 
      {
         Monitor.Exit(instanceLock);
      }
    }

这是监视器锁定的正确方式

bool isLocked = false;
try
{
 Monitor.Enter(instanceLock , ref isLocked);
 // Do some things within the lock    
}
finally
{
 if (isLocked) Monitor.Exit(instanceLock);
}

至于cer.mayfail,此链接将提供更多信息

对不起,但是您在发布的代码中到底在哪里看到“ConstrainedExecution”?
cer
==
受约束的执行区域
,mb?@ShadowWizard:我害怕
cer.mayfail
,那么什么可能会失败呢?对象创建或其他内容。您可以选择阅读此内容,也可以查看undefined关于错误处理的回答。很好。你是说
new Object()
可能会失败,因为在任何try-catch中都没有失败,所以我的程序可能会崩溃,对吗?不,假设你在一个方法中有一些操作。并且在执行该方法的中间,抛出异常;然后,应用于此方法中的对象直到异常点的更改将不会回滚。如果关键区域中存在未处理的异常,则明智的做法是“泄漏”锁(并最终优雅地关闭当前应用程序域)而不是释放一些线程来处理损坏的共享状态数据……只有在能够确保每个线程都能在共享数据的“正确”状态下工作时,才应该释放锁(即,在出现异常时回滚到正确状态)…确保共享状态的正确性是使用锁的首要原因…这就是为什么“lock”关键字不是关键区域锁定的好候选项
lock
语句不是您所写内容的语法糖,即
try{Monitor.TryEnter(..)finally{Monitor.Exit(..);}
,相反,它是
try{Monitor.Enter(..)}finally{Monitor.Exit(..);}
的语法糖。注意
TryEnter()
Enter()
之间的区别。