在 UI 线程上创建并启动任务

2024-04-24

当在工作线程上调用的方法需要在 UI 线程上运行代码并等待其完成后再执行其他操作时,可以这样做:

    public int RunOnUi(Func<int> f)
    {
        int res = Application.Current.Dispatcher.Invoke(f);

        return res;
    }

但如果我想用任务来做呢?有没有办法让 RunOnUi 方法创建一个在 UI 上启动的任务并返回它,以便调用者(在工作线程上运行)可以等待它?符合以下签名的东西:public Task<int> StartOnUi(Func<int> f) ?

一种方法如下:

public Task<int> RunOnUi(Func<int> f)
{
    var task = new Task<int>(f);
    task.Start(_scheduler);

    return task;
}

在这里,假设_schduler持有用户界面TaskScheduler。但我不太习惯创建“冷”任务并使用 start 方法来运行它们。这是“推荐”的方式还是有更优雅的方式来做到这一点?


只需使用InvokeAsync https://msdn.microsoft.com/en-us/library/hh199385(v=vs.110).aspx代替Invoke然后返回Task<int>在 - 的里面DispatcherOperation<int> https://msdn.microsoft.com/en-us/library/hh199421(v=vs.110).aspx函数返回。

//Coding conventions say async functions should end with the word Async.
public Task<int> RunOnUiAsync(Func<int> f)
{
    var dispatcherOperation = Application.Current.Dispatcher.InvokeAsync(f);
    return dispatcherOperation.Task;
}

如果您无法访问 .NET 4.5,情况会稍微复杂一些。您将需要使用BeginInvoke https://msdn.microsoft.com/en-us/library/cc190824(v=vs.110).aspx and a TaskCompletionSource https://msdn.microsoft.com/en-us/library/dd449174(v=vs.110).aspx包裹DispaterOperation https://msdn.microsoft.com/en-us/library/System.Windows.Threading.DispatcherOperation(v=vs.100).aspx that BeginInvoke returns

    public Task<int> RunOnUi(Func<int> f)
    {
        var operation = Application.Current.Dispatcher.BeginInvoke(f);
        var tcs = new TaskCompletionSource<int>();
        operation.Aborted += (sender, args) => tcs.TrySetException(new SomeExecptionHere());
        operation.Completed += (sender, args) => tcs.TrySetResult((int)operation.Result);

        //The operation may have already finished and this check accounts for 
        //the race condition where neither of the events will ever be called
        //because the events where raised before you subscribed.
        var status = operation.Status;
        if (status == DispatcherOperationStatus.Completed)
        {
            tcs.TrySetResult((int)operation.Result);
        }
        else if (status == DispatcherOperationStatus.Aborted)
        {
            tcs.TrySetException(new SomeExecptionHere());
        }

        return tcs.Task;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 UI 线程上创建并启动任务 的相关文章

  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 检测 TextBox 中的 Tab 键按下

    I am trying to detect the Tab key press in a TextBox I know that the Tab key does not trigger the KeyDown KeyUp or the K
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 如何设置消息队列的所有者?

    System Messaging MessageQueue 类不提供设置队列所有权的方法 如何以编程方式设置 MSMQ 消息队列的所有者 简短的答案是 p invoke 对 windows api 函数的调用MQSetQueueSecuri
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 选择 asp.net CheckBoxList 中的所有项目

    ASP NET 和 C 我想要一个带有 全选 项目的复选框列表 当这个特定项目是 已选择 所有其他都将被选择 也 当选择被删除时 这个项目 也将来自所有人 其他物品 选中 取消选中 任何其他项目只会有一个 对特定项目的影响 无论选择状态如何
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 在 Qt 中播放通知(频率 x)声音 - 最简单的方法?

    Qt 5 1 或更高版本 我需要播放频率为 x 的通知声音 n 毫秒 如果我能像这样组合音调那就太好了 1000Hz 持续 2 秒 然后 3000Hz 持续 1 秒 最简单的方法是使用文件 WAV MP3 例如如此处所述 如何用Qt播放声音
  • 如何调用与现有方法同名的扩展方法? [复制]

    这个问题在这里已经有答案了 我有这样的代码 public class TestA public string ColA get set public string ColB get set public string ColC get se
  • 时间:2019-03-17 标签:c#TimerStopConfusion

    我想通过单击按钮时更改文本颜色来将文本框文本设置为 闪烁 我可以让文本按照我想要的方式闪烁 但我希望它在闪烁几次后停止 我不知道如何在计时器触发几次后让它停止 这是我的代码 public Form1 InitializeComponent
  • 当 Verb="runas" 时设置 ProcessStartInfo.EnvironmentVariables

    我正在开发一个 C 应用程序 我需要创建变量并将其传递给新进程 我正在使用ProcessStartInfo EnvironmentVariables 新进程必须提升运行 因此我使用 Verb runas var startInfo new
  • 在 C 中使用 #define 没有任何价值

    If a define没有任何价值地使用 例如 define COMMAND SPI 默认值是0吗 不 它的评估结果为零 从字面上看 该符号被替换为空 然而 一旦你有了 define FOO 预处理器条件 ifdef FOO现在将是真的 另
  • Unity,c++ 本机插件字节数组不匹配

    在我的 C 本机插件中 我有一个调用 vector
  • IDisposable 的显式实现

    虽然有很多关于IDisposable在 SO 上找到 我还没有找到答案 我通常遵循这样的做法 当我的一个班级拥有一个IDisposable对象然后它也实现IDisposable并打电话Dispose在拥有的对象上 然而最近我遇到了一个类 它
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe

随机推荐

  • 如何在 Symfony2 控制台命令中设置环境

    希望这是一个简单的问题 在 Symfony2 中运行控制台命令时如何指定使用哪个环境 我创建了一些命令 但是我想在我的临时服务器上的 临时 环境上下文中运行它们 在生产服务器上时在 产品 环境中运行它们 不同的环境定义不同的数据库连接 如何
  • 如何使用 Log4cxx 或 log4j 记录进程 ID

    我正在使用 log4cxx 我的项目 我可以使用 t 标记记录当前线程 id 如何在其中记录进程 id 或 log4j 我正在使用 ConversionPattern 和基于 xml 的配置文件 谢谢 基于以上答案 我将在 log4j 中执
  • 如何修复此警告“useLayoutEffect”相关警告?

    我将 NextJS 与 Material UI 和 Apollo 结合使用 虽然一切正常 但警告没有消失 在我看来 很多 Material UI 组件都在使用使用布局效果React 会发出警告 错误如下 警告 useLayoutEffect
  • ReferenceError:使用 CKEditor 时未定义 self [重复]

    这个问题在这里已经有答案了 ReferenceError 导入 CKEditor 时未定义 self 我正在使用 next js import CKEditor from ckeditor ckeditor5 react 已经安装使用 np
  • float 和 double 精度相关的概念

    为什么精度float小数点后最多 6 位 精度double小数点后最多15位 任何人都可以给一个数学解释 of it 说一下精度float or double是一些小数位数是草率的术语 float and double通常使用 IEEE 7
  • 输入具有最小和最大数字的值

    下面是一个输入数字表单 我使用 JavaScript 添加了一些代码 其中可写入的最小数字为 1 最大可写入数字为 50 当有人尝试输入任何小于 1 且大于 50 的数字时 它会自动将其替换为数字 1 或 50 但我没有成功实现此目标 我需
  • 为什么一个简单的 get 语句这么慢?

    几年前 我在学校接到一项作业 必须并行化光线追踪器 这是一项简单的任务 我真的很喜欢做它 今天 我想对光线追踪器进行分析 看看是否可以让它运行得更快 无需完全修改代码 在分析过程中 我注意到一些有趣的事情 Sphere Intersect
  • 使用 rMarkdown 自动生成报告

    我试图在 rMarkdown 中使用相同的模板生成大约 50 份报告 我不想每次都更改输入文件的名称 并且我想为输出文件选择不同的名称 有什么办法可以自动化这个过程吗 谢谢 另一种选择是在单独的 R 脚本中使用 rmarkdown 包的 r
  • Python OpenCV cv.WaitKey 在 Ubuntu 模 256 映射上正确返回奇怪的输出

    我正在使用 OpenCV 2 2 运行 Ubuntu 11 10 Lenovo T400 我相信导入是通过 import cv2 cv as cv 完成的 如果我只是 导入简历 也会发生这个问题 我最近开始遇到这个问题 这有点奇怪 我不知道
  • 使用 EF6(实体框架 6)编写单元测试

    我有一个使用 NET Framework 4 6 1 和 EF6 的 ASP NET Core 项目 现在我想编写一些单元测试 并且已经花了几个小时来配置内存 SQLite 数据库以使用 EF6 但这不起作用 所以 问题是如何使用 EF6
  • 如何在C++中读取一个字节并将字节的ASCII值保存为整数

    我有一个简单的问题让我困惑 Goal 我想从文件中读取给定的字节 比如第一个字节 并用该字节的 ASCII 值创建 int x 因此 例如 如果字节 字符是 a 我希望 x 为 97 十六进制的 61 我有以下读取文件 example tx
  • ANDROID - 在列表视图中获取选定的 id 评级栏

    我试图找出如何获取所选的 idratingBar in ListView在网上 但大多数人都使用ListViewAdapter or RatingAdapter在另一堂课上 我不知道该怎么做 因为我还不知道 所以我所有的课程都在MainAc
  • 通过 IPython 使用 Jython:readline 仍然是一个问题吗?

    我想将 Jython 解释器与 IPython 一起使用 这样我就可以使用制表符补全之类的东西 也许还可以使用 IPython 笔记本 这IPython 常见问题解答网站 http ipython org faq html围绕这是否可行采取
  • React Navigation - setOptions() headerRight 回调中的访问状态

    我凌驾于一切之上反应导航 https reactnavigation org headerRight内部带有自定义按钮的选项React useEffect 当按下按钮时 我需要访问状态name但我得到的值不是当前的值 const name
  • 强制设置核心数据检查点?

    我编写了一个通过 Core Data 搅动大量数据的应用程序 用户在后台退出应用程序后 我会清理这些数据 由于 WAL 检查点似乎是导致 UI 暂停的主要原因 因此我还想强制使用 WAL 检查点 是的 我知道创建第二个核心数据堆栈 这也将完
  • 手动启动 SharePoint 计时器作业

    我想手动调用安装在 SharePoint 服务器上的计时器作业 有用的是类似于 stsadm 命令的东西 我的场景是 我已将具有大量功能的解决方案部署到客户服务器 我不想等待每周的时间表来启动特定的计时器工作 我想输入一个命令来立即运行特定
  • 为什么after_find和after_initialize事件的回调要将它们定义为方法?

    定义 after find 和 after initialize 事件回调的唯一方法是将它们定义为方法 如果您尝试使用第二种技术将它们声明为处理程序 它们将被默默地忽略 有人能解释一下为什么会这样吗 为什么专门针对这两个回调呢 EDIT 摘
  • XML 和 Python:获取根元素中声明的命名空间

    如何访问多个xmlnsXML 树根元素的声明 例如 import xml etree cElementTree as ET data
  • 使用 load_model 加载经过训练的tensorflow.keras模型会返回JSON解码错误,而未经训练的模型加载正常

    我有一个训练有素的 Keras 模型 使用 tensorflow keras API 构建和训练 并使用tf keras save model 没有可选参数的方法 Tensorflow 是最新的 我的 Python 版本是 3 8 根据我的
  • 在 UI 线程上创建并启动任务

    当在工作线程上调用的方法需要在 UI 线程上运行代码并等待其完成后再执行其他操作时 可以这样做 public int RunOnUi Func