问题标签 [iprogress]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
163 浏览

c# - MVC 模型中的 IProgress 通知

我已经开始在我的 MVC 应用程序(桌面)中使用 IProgress 和 async/await,但我对整个事情的设计有点困惑。

我有一个表单/视图 V,它开始下载数据的操作。V,将调用控制器 C 开始下载/请求数据,然后调用 Model M 开始实际下载(从 web 服务或任何数据源)。

现在我希望 M 在下载中有进度更新时通知 V(iew)。为此,通知应通过 C:

V-->C-->M 然后 M-->C-->V

使用 IProgress,我应该将 IProgress 实现从 V 一直发送到 M。通知应该从那里触发。我见过的所有示例都只有 2 个类/层来实现简单的实现。

我的方法正确吗?

0 投票
1 回答
582 浏览

c# - 并非 IProgress 的所有结果从任务中走出来

考虑以下实现,一个方法接受一个IProgress<int>,迭代超过 10000 个对象。数组变量返回 10000 个对象,numbersIProgress<int>报告仅在 9970 - 9980 个对象之间。每次运行都会有所不同,因此有些人会“迷路”。

作为参考,这是我运行的测试。它在第三个 assert 失败Assert.Equal(10000, result[9999]);

显然我做错了什么,或者我不了解任务/线程的内部结构。我的执行IProgress<int>new Progress<int>(i => result.Add(i))正确吗?我应该让那个线程安全吗?如果是,我该怎么做?

如果需要,GitHub 有您可以克隆和测试的代码:https ://github.com/KodeFoxx/Kf.DataCollection/tree/master/Source/Kf.DataCollection

0 投票
0 回答
247 浏览

c# - 基于任务的异步模式不支持 System.IProgress

我有一个 WCF 服务,IMyService。在此服务中,有一个使用 System.IProgress 的操作。

我使用 Autofac 为 IMyService 服务创建客户端

现在,我收到此错误:

错误是关于基于任务的异步模式不支持 IProgress。这似乎不对,请有人帮忙。

0 投票
2 回答
785 浏览

c# - 使用 IProgress.Report() 报告进度时,控制台消息显示顺序不正确

我注意到以下行为。当 IProgress 填充控制台输出消息时,它们会出现在不正确的文件夹中。

我正在努力提高我的封装、可重用性和设计技能。所以,我有一个名为 IdRecounter 的类。我现在想在控制台应用程序中使用它,但稍后可能会在 WPF 应用程序或其他应用程序中使用它。

因此,我希望班级完全不知道它的环境——但同时我想报告“实时”动作的进度——因此,我使用 IProgress 类型,这将允许我将内容放入控制台,或者进入日志文件,或更新状态标签属性等。(如果您不是这样做的,请告诉我)

所以,我注意到它倾向于以错误的顺序将消息抛出到控制台,例如处理文件 1
处理文件 4
处理文件 5
处理文件 3
全部完成!
处理文件 2

当我切换 IProgress ( MyProgress.Report()) 时,Console.WriteLine()它按预期工作。
这是什么原因,如何控制?

谢谢

0 投票
1 回答
746 浏览

asynchronous - 通过 MVC 控制器的 SignalR 进度

工作流程场景

上图代表我要解决的场景。

根据我之前的经验,我知道进度报告模式可用于解决保持客户端更新但当时客户端直接与集线器通信的问题,这意味着背后没有控制器或代码。

在上图中,问题是控制器在调用数据库之前需要做一些事情。

此外,数据库以文件的形式返回段,因此我添加了一个异步文件系统观察器,用于在每次创建响应文件时通知我。

目标是在您收到响应段时继续为客户端浏览器提供响应段,直到我们到达响应的末尾。

问题是:如何从控制器/服务方法触发 signalR Hub 并继续向客户端浏览器提供响应?

更新:

缩小问题范围

  1. 我的控制器调用服务方法

    /li>
  2. 在该ResponseFilewaiterAsync方法中,当创建第一个文件时,我触发集线器

    /li>
  3. 集线器将响应报告给客户端并查找下一个文件,直到完成

    /li>

问题:如何从服务方法/控制器触发进度报告中心?更新完成后我应该在哪里完成我的请求——它应该返回到控制器吗?

0 投票
1 回答
346 浏览

c# - 进步和 Parallel.ForEach 同步问题

我遇到了一个同步问题,涉及在 Parallel.ForEach 内报告进度。我在控制台应用程序中重新创建了问题的简化版本。该示例实际上只使用了列表中的一项。这是代码:

在此处输入图像描述

如您所见,我希望最后看到的行不是最后输出,也不包含 20。但是,如果我删除进度报告并像这样在 for 循环中写入输出:

在此处输入图像描述

它的行为就像我预期的那样。据我所知,Parallel.ForEach 为列表中的每个项目创建一个任务,而 IProgress 捕获创建它的上下文。鉴于它是一个控制台应用程序,我认为这并不重要。请帮忙!

0 投票
1 回答
126 浏览

asynchronous - 在 await 返回后执行 C# Progress 方法

我第一次尝试异步等待并遇到使用进度的问题。我使用 await 调用我的异步方法并传入我的进度操作。我想要发生的是显示进度,当方法完成消息说我们“完成!” 被展示。发生的情况是显示进度,“完成!” 显示,然后是最后一条进度消息,这是输出示例:1、2、

完毕!3

似乎异步已返回,并且 UI 上下文在最终进度有机会运行之前执行。我可以通过添加处理程序来克服这个问题,但要正确地遵循模式。

0 投票
1 回答
204 浏览

c# - 如何用任务包装 EAP 模式方法和 IProgress

我正在使用我自己的“旧”库中的一堆同步函数。这些用于备份文件,压缩它们并按示例上传它们。为了进一步使用,我想将这些更改为异步函数。请原谅我下面的长篇介绍,但这个问题需要一些背景知识..

我找到了一些关于如何转换它的信息:

一本好书:Stephen Cleary 的 C# Cookbook 中的并发。

这是我尝试熟练使用的示例模式:

这里还有一些帖子:

要点:

  • 一直使用 Async /Await
  • 不要用结果或等待将同步方法包装在异步模式中。尽可能使用 await
  • 将 EAP 模式方法包装到任务中
  • 避免在库中使用 Task.Run
  • 在库中使用 ConfigureAwait(False)
  • 在您的 UI 中改用 Task.Run
  • 使用 IProgress 发布进度

我的基本课程如下所示:

(对于我现在使用 IProgress 的进度,所以我删除了这个类中的旧行)

此类用于库的最高级功能,应跟踪所有不同的操作,例如使用 SevenZipSharp 压缩目录:

正如你所看到的,我使用事件处理程序来发送我的类的对象,以便能够在进度之外捕获其他信息,如操作、状态或状态详细信息。所以现在我的问题:

对于基于异步任务的方法,应将其转换为如下模式:

这意味着我需要将上述函数包装到此。SevenZipSharp 中的事件处理程序使用 EventArgs,而不是 AsyncCompletedEventArgs 的后代。有更好的方法吗?

更新 2: 我将压缩部分包装到一个任务中,以便能够在需要时取消它。SevenZipCompressor 不支持取消。所以通常我应该避免在库中的task.run,但不知道替代方案。我也确实更改了 BeginCompressDirectoy,因为它在开始压缩后立即返回,而不是像 CompressDirectory 那样阻塞线程直到完成。到目前为止,进展有效,但取消 NOT。只需一小步即可完成左侧...希望您能提供帮助。

!!要测试此功能,您只需要安装 nuget 包 Squid-Box.SevenZipSharp !

到目前为止,我已经尝试像这样包装 SevenZipCompressor:

0 投票
2 回答
795 浏览

c# - 在 await Task.Run 调用中使用 TaskCompletionSource

我遇到了一些意想不到的行为,我想对此有所了解。我创建了一个简单的例子来演示这个问题。我使用 调用异步函数Task.Run,它将不断生成结果,并用于IProgress向 UI 传递更新。但是我想等到 UI 实际更新后再继续,所以我尝试按照其他一些帖子中的建议使用 TaskCompletionSource(这似乎有点相似:Is it possible to await an event instead of another async method?.)我期待最初Task.Run的等待,但正在发生的是内部发生的等待似乎将其向前移动,并且“END”发生在第一次迭代之后。Start()是入口点:

有了这个,我得到:

而不是我想要得到的是:

我假设我对 Tasks 和 await 以及它们的工作方式有误解。我确实想StartDataPush成为一个单独的线程,我的理解是它是。我的最终用途有点复杂,因为它涉及繁重的计算、更新到 WPF UI 以及发回通知它已完成的事件,但机制是相同的。我怎样才能实现我想要做的事情?

0 投票
4 回答
546 浏览

c# - 如何同步共享的 IProgress

我有一个异步方法DoStuffAsync,它使用 生成两个任务Task.Run,并且两个任务都使用单个IProgress<int>对象报告它们的进度。从用户的角度来看,只有一个操作,因此显示两个进度条(每个进度条一个Task)没有任何意义。这就是IProgress<int>共享的原因。问题是有时 UI 以错误的顺序接收进度通知。这是我的代码:

大多数情况下,通知的顺序是正确的,但有时它们不是:

截图

这会导致ProgressBar控件(上面的屏幕截图中未显示)笨拙地来回跳跃。

作为临时解决方案,我在方法lock内部添加了一个DoStuffAsync,其中包括方法的调用IProgress.Report

虽然这解决了问题,但它让我感到焦虑,因为我在持有lock. 该DoStuffAsync方法实际上是库的一部分,可以使用任何IProgress<int>实现作为参数调用。这开启了死锁场景的可能性。有没有更好的方法来实现该DoStuffAsync方法,而不使用 a lock,但具有关于通知排序的所需行为?