c# - 使用 Monitor.Exit 引发的异常
问题描述
我似乎无法弄清楚为什么我会得到这个例外。这是我正在运行的代码和我尝试过的事情。
public static Boolean IsRunning = false;
public static void Process()
{
Boolean lockTaken = false;
try
{
Monitor.TryEnter(IsRunning, ref lockTaken);
if (lockTaken)
{
// Run code
}
}
catch (Exception e) { e.Log(); }
finally
{
if (lockTaken)
{
Monitor.Exit(IsRunning);
}
}
}
出于某种原因,我在该Monitor.Exit(IsRunning);
行引发了异常,这很奇怪,因为如果监视器成功获得对象的锁定,我只运行该行代码IsRunning
。任何可能导致抛出此异常的线索?
抛出的异常是从未同步的代码块调用对象同步方法。
解决方案
嗯...属性IsRunning
的类型System.Boolean
是值类型或结构。您只能在引用类型的实例上设置锁定。
在这里您可以阅读有关Monitor
课程的信息:https ://docs.microsoft.com/en-us/dotnet/api/system.threading.monitor?view=netcore-3.1
在这里您可以阅读有关值和引用类型的信息:https ://www.tutorialsteacher.com/csharp/csharp-value-type-and-reference-type
当您将值类型的实例作为 aSystem.Object
或通过接口传递给方法时,就会发生装箱分配。
它是什么?
CLR 分配内存,然后将传递的实例的值复制到堆中,并将对分配对象的引用真正传递给被调用的方法。因此,当您调用Enter
CLR 时,它会分配一个新对象并将它的引用传递给该方法。当您调用Exit
它时,它会再分配一个新对象,并且它是另一个对象。所以当前线程没有锁定它。这就是引发异常的原因。
您可以在此处阅读有关装箱和拆箱的信息:https ://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxing#:~:text=Boxing%20is%20the% 20 进程%20 的值%20 类型%20 来自%20%20 对象。
推荐阅读
- reactjs - 从另一个类调用 React 中的 handleSubmit
- vue.js - 推文按钮数据 URL 未在更改时更新
- javascript - Victory onClick 事件不更新填充颜色
- c++ - 我怎样才能为我自己的班级专门化一个标准概念?
- mobx - 我可以创建一个在 React 渲染函数中计算的 mobx 以像 useMemo() 一样使用吗?
- html - 如何在html中使用jpg作为背景图片
- clojure - 你如何用空格分割用户输入的字符串
- amazon-web-services - AWS:阻止所有存储桶公共访问会影响来自其他 AWS 账户的访问吗?
- python - 如何创建 json 限制?(不和谐)
- laravel - Invisnik Laravel Steamauth 登录错误