从 Lock() 内调用 UI 线程上的方法

2024-02-15

我有两种方法,MethodA & MethodB. MethodB必须在 UI 线程上运行。我需要他们在不允许的情况下一个接一个地运行MethodC在他们之间奔跑。

MethodC当用户单击一个可爱的小按钮时调用。

我做了什么来确保这是一个Lock围绕代码:

 lock (MyLock)
 {
   MethodA(param1, param2);

   MyDelegate del = new MyDelegate(MethodB);
   if (this.IsHandleCreated) this.Invoke(del);
 }

And for MethodC:

public void MethodC()
 lock (MyLock)
 {
   Do bewildering stuff.....
 }

问题是我被卡住了。看起来我的代码陷入了僵局。

当我查看线程时,我发现按钮单击调用的代码被卡在lock (MyLock) in MethodC我的另一个线程似乎卡在this.Invoke(del).

我读过从内部调用方法是危险的Lock但因为我是在那里编写代码的人,即使只用一个,这似乎也会发生Thread.Sleep我认为这不是给我带来麻烦的代码。

为什么 Invoked 方法会停止工作? 是否有可能等待锁定methodC在返回到调用它的原始锁之前要释放它吗?


那么,想象一下以下情况:

  1. 您的后台线程开始运行代码。它抓住锁然后开始运行MethodA.

  2. MethodC被调用时MethodA正在工作中。MethodA等待锁释放,并阻塞 UI 线程,直到释放为止。

  3. 后台线程结束MethodA并去调用MethodB在 UI 线程上。MethodB在消息泵队列中的所有先前项目完成之前无法运行。

  4. MethodC位于消息泵队列的顶部,等待直到MethodB完成,并且MethodB在队列中等待直到MethodC完成。两人都在等待对方,陷入了僵局。

那么,你如何解决这个问题呢?你什么reallyneed 是某种“等待”锁而不实际阻塞线程的方式。幸运的是(在 .NET 4.5 中)借助任务并行库,这很容易做到。 (我在引号中等待,因为我们实际上不想等待,我们只想执行MethodC一旦锁被释放without实际上正在等待/阻塞当前线程。)

而不是使用object for MyLock use:

private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);

Now for MethodC你可以做:

public async Task MethodC() //you can change the signature to return `void` if this is an event handler
{
    try
    {
        await semaphore.WaitAsync();
        //Do stuff
    }
    finally
    {
        semaphore.Release();
    }
}

这里的关键是因为我们await代表信号量何时实际空闲的任务,我们不会阻塞当前线程,这将允许其他后台任务进行编组MethodB到UI线程,完成该方法,释放信号量,然后让该方法执行。

您的其他代码不需要(但如果您愿意,仍然可以)使用信号量上的异步等待;阻塞后台线程并不是什么大问题,因此唯一的关键更改是使用信号量而不是lock:

public void Bar()
{
    try
    {
        semaphore.Wait();
        MethodA(param1, param2);

        MyDelegate del = new MyDelegate(MethodB);
        if (this.IsHandleCreated) this.Invoke(del);
    }
    finally
    {
        semaphore.Release();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Lock() 内调用 UI 线程上的方法 的相关文章

  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 如果.Net Core可以在Windows上运行,为什么不能在.Net Framework中引用.Net Core DLL?

    我明白为什么 Net Framework 可能会在 Net Core IE 中导致问题 因为不存在特定于 Windows 平台的 API 但是为什么不能直接引用 Net Core 作为 Net Framework 中的库呢 如果 Net C
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 两组点之间的最佳匹配

    I ve got two lists of points let s call them L1 P1 x1 y1 Pn xn yn and L2 P 1 x 1 y 1 P n x n y n 我的任务是找到它们点之间的最佳匹配 以最小化它
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 无法使用 Ninject 将依赖项注入到从 Angular 服务调用的 ASP.NET Web API 控制器中

    我将 Ninject 与 ASP NET MVC 4 一起使用 我正在使用存储库 并希望进行构造函数注入以将存储库传递给其中一个控制器 这是实现 StatTracker 接口的上下文对象 EntityFramework public cla
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • 如何重新启动死线程? [复制]

    这个问题在这里已经有答案了 有哪些不同的可能性可以带来死线程回到可运行状态 如果您查看线程生命周期图像 就会发现一旦线程终止 您就无法返回到新位置 So 没有办法将死线程恢复到可运行状态 相反 您应该创建一个新的 Thread 实例
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem

随机推荐

  • 查询范围不等于0

    我在 AX 2012 R2 环境中 我想向 HcmEmployment 表添加查询范围并过滤掉 LegalEntity 值 0 的行 以下代码在运行时失败 并出现 无效范围 异常 qbrLegalEntity qbds addRange f
  • 引用列的统计信息是否会阻止删除该列?

    我正在尝试一个非常简单的drop column陈述 alter table MyTable drop column MyColumn 并收到几个错误 消息 5074 16 级 状态 1 第 1 行统计信息 dta stat 12682516
  • QML 中日期和时间的正则表达式(DD/MM/YYYY hh:mm:ss)

    在QML2中我没有找到任何Calender控件 我已经实现了一个以日期和时间作为输入的控件 并且我使用正则表达式进行验证 该验证与日期 包括闰年和其他验证 相匹配 主要问题是空格 退格键也应该被视为有效 例如 s s s s s s s s
  • Flexbox - 首先在新行上换行中心项目

    我正在使用 Flex Box 创建传统的浮动项目列表 我有三个项目 结构如下 section div item one div div item two div div item three div section 与CSS section
  • Bash:将来自多个 xargs 并行进程的标准输出记录到单独的日志文件中

    我正在处理一个文本文件 其中包含由 xargs 生成的多个并行进程 我还需要将每个进程的标准输出捕获到单独的日志文件中 下面是一个示例 其中每个进程的输出被交错到一个文件中 这不是我想要的 理想情况下 每个日志文件应按文件行号进行编号 即
  • Tiff 中的 Jpeg(jpeg 压缩)

    如何从 JPEG 压缩的 TIFF 文件中提取图像 我已根据 StripOffests 和 StripBytesCount 字段读取字节 但无法从中加载图像 旧式 TIFF JPEG 压缩类型 6 基本上将普通 JFIF 文件填充到 TIF
  • Haven::read_sav 显示值标签而不是代码

    我在用着haven导入一个 sav文件到R 我想知道如何显示值标签而不是数字代码 在下面的示例中 我想显示物种名称而不是数字 1 2 3 library haven path lt system file examples iris sav
  • 如何使用交错的 Huggingface 数据集创建 PyTorch 数据加载器?

    当我交错数据集 获取标记化批次 将批次提供给 pytorch 数据加载器时 我收到错误 coding utf 8 issues with dataloader and custom data sets Automatically gener
  • Ant:如果目录不存在,如何忽略构建错误?

    我正在使用 Ant 1 8 1 如果目录不存在 如何忽略以下构建错误 我得到的错误是 BUILD FAILED Users davea myco2 myco build xml 211 Directory does not exist Us
  • 路由前的角度动画

    在我当前的项目中 我试图摆脱路由时跳过的 Angular 动画 在我的模板中 我有不同的 小部件 mat card在 css grid 布局中 我想让它平滑地出现和消失 我的子组件中的动画 路线指向的 看起来像 animations tri
  • `JTableHeader` 可以跨越多个列吗?

    我花了很长时间寻找这个 但我只找到了GroupableHeader代码 我需要 2 列中的 2 列上有一个标题JTable 如果不使用臭名昭著的方法 如何才能做到这一点 GroupableHeader 同时保持 JTableHeader 的
  • 如何在 R 中引用查找表将两个 data.frame 合并在一起

    我正在尝试合并两个data frames一起 基于每个中的公共列名称称为series id 这是我的合并语句 merge test growth series LUT test growth series by intersect seri
  • 如何通过链接描述文件将符号放置在特定地址处?

    这是关于 GNU Linker 的 我有一个 可以说 名为的变量myVar 现在我希望我的变量被放置在内存中的某个地址 我使用的编译器有一个 attribute blablabla 这样就可以了 不过我决定使用链接描述文件 从现在开始 我设
  • ReentrantReadWriteLock 中的公平锁定

    B Goetz 所著的 Java Concurrency In Practice 中 第 13 5 节说道 在 Java 5 0 中 读锁的行为更像是信号量而不是锁 仅维护活跃读者的数量 而不维护他们的身份 Java 6 中的行为已更改 以
  • 中断安全 FIFO 中的 DMB 指令

    相关这个线程 https stackoverflow com q 50800118 1488067 我有一个 FIFO 它应该可以跨 Cortex M4 上的不同中断工作 头部索引必须是 由以下人员原子编写 修改 多个中断 不是线程 通过单
  • 如何在 MVC 中创建国家和州/省的选择列表

    嗨 我是 MVC 甚至 asp 的新手 我想在 MVC 中创建一个表单 在一些示例的帮助下 我可以创建文本框 但我现在不明白如何创建选择列表 我尝试搜索许多在 MVC 中实现选择列表的示例 但我无法理解 我有一个表单 一半用 HTML 编码
  • C# 是否允许使用双分号 ; ;如果可以的话,有什么特殊的方法吗?

    我正在编写一条语句并且它可以编译 但编译器 VS 从未告诉我我放置了两次分号 这意味着在 ASP NET MVC 3 中 return Json mydata return Json mydata 两者都可以编译 但第一个在设计模式上是错误
  • Retrofit 仅在第一次给出 EOFException

    我第一次在我的 Android 项目中使用框架 Retrofit 它处理与后端的通信 现在最奇怪的部分是 在 Android 4 4 上 一切都像魅力一样 在下面的每个版本上 我得到一个 RetrofitError 类型 java io E
  • Android Studio:如何将我的 .aar 库链接到多个项目?

    我有一个在多个项目中使用的库 每次更新 和重建 此库时 我不想将 aar 复制并粘贴到使用此库的每个项目中 实现这一目标最方便 最有效的方法是什么 注意 我在 Mac OSX 上运行 Android Studio 1 0 RC2 将您的 A
  • 从 Lock() 内调用 UI 线程上的方法

    我有两种方法 MethodA MethodB MethodB必须在 UI 线程上运行 我需要他们在不允许的情况下一个接一个地运行MethodC在他们之间奔跑 MethodC当用户单击一个可爱的小按钮时调用 我做了什么来确保这是一个Lock围