- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在试验异步/等待和进度报告,因此编写了一个异步文件复制方法,在每个复制 MB 后报告进度:
public async Task CopyFileAsync(string sourceFile, string destFile, CancellationToken ct, IProgress<int> progress) {
var bufferSize = 1024*1024 ;
byte[] bytes = new byte[bufferSize];
using(var source = new FileStream(sourceFile, FileMode.Open, FileAccess.Read)){
using(var dest = new FileStream(destFile, FileMode.Create, FileAccess.Write)){
var totalBytes = source.Length;
var copiedBytes = 0;
var bytesRead = -1;
while ((bytesRead = await source.ReadAsync(bytes, 0, bufferSize, ct)) > 0)
{
await dest.WriteAsync(bytes, 0, bytesRead, ct);
copiedBytes += bytesRead;
progress?.Report((int)(copiedBytes * 100 / totalBytes));
}
}
}
}
在控制台应用程序中创建随机内容为 10MB 的 I 文件,然后使用上述方法复制它:
private void MainProgram(string[] args)
{
Console.WriteLine("Create File...");
var dir = Path.GetDirectoryName(typeof(MainClass).Assembly.Location);
var file = Path.Combine(dir, "file.txt");
var dest = Path.Combine(dir, "fileCopy.txt");
var rnd = new Random();
const string chars = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
var str = new string(Enumerable
.Range(0, 1024*1024*10)
.Select(i => letters[rnd.Next(chars.Length -1)])
.ToArray());
File.WriteAllText(file, str);
var source = new CancellationTokenSource();
var token = source.Token;
var progress = new Progress<int>();
progress.ProgressChanged += (sender, percent) => Console.WriteLine($"Progress: {percent}%");
var task = CopyFileAsync(file, dest, token, progress);
Console.WriteLine("Start Copy...");
Console.ReadLine();
}
应用程序执行后,两个文件是相同的,因此复制过程以正确的顺序执行。但是,控制台输出类似于:
Create File...
Start Copy...
Progress: 10%
Progress: 30%
Progress: 20%
Progress: 60%
Progress: 50%
Progress: 70%
Progress: 80%
Progress: 40%
Progress: 90%
Progress: 100%
每次我调用应用程序时顺序都不同。我不明白这种行为。如果我在事件处理程序中放置一个断点并检查每个值,它们的顺序是正确的。谁能给我解释一下?
我想稍后在带有进度条的 GUI 应用程序中使用它,并且不想让它一直来回跳转。
最佳答案
Progress<T>
捕获电流 SynchronizationContext
创建时。如果没有SynchronizationContext
(就像在控制台应用程序中一样)- 进度回调将被安排到线程池线程。这意味着多个回调甚至可以并行运行,当然不能保证顺序。
在 UI 应用程序中,发布到同步上下文大致等同于:
在 WPF 中:Dispatcher.BeginInvoke()
在 WinForms 中:Control.BeginInvoke
我没有使用 WinForms,但在 WPF 中,多个 BeginInvoke
具有相同优先级(在本例中它们具有相同优先级)的是 guaranteed按照它们被调用的顺序执行:
multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made.
我不明白为什么在 WinForms 中 Control.BeginInvoke
可能会执行我们的命令,但我不知道我上面为 WPF 提供的证明。因此,我认为在 WPF 和 WinForms 中,您可以安全地依赖按顺序执行的进度回调(前提是您在 UI 线程上创建了 Progress<T>
实例本身,以便可以捕获上下文)。
站点注释:不要忘记添加 ConfigureAwait(false)
给你的ReadAsync
和 WriteAsync
每次调用以防止在 UI 应用程序中返回到 UI 线程 await
关于C# async/await 进度报告不符合预期顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47607932/
我们如何让 SwiftUI 对象,尤其是 Image,符合 Hashable 协议(protocol)? 我知道它们符合 Equatable 协议(protocol),所以主要问题是如何获取哈希值,或
我遇到了一些符合 AVAudioPlayerDelegate 的奇怪问题。以下正是我在一个全新的 Xcode 项目中所拥有的: import UIKit import AVFoundation cla
我一辈子都弄不明白为什么我会收到此类不符合 NSCoding 协议(protocol)的错误。也许另一双眼睛会有所帮助。我试图添加注释以明确每个函数在做什么。 import Foundation im
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
所有现代浏览器都理解 HTML,所以除了在键盘最右侧编写更多字符之外,兼容 XHTML 的意义何在。 最佳答案 没有一点我能想到的。 W3C 已经取消了 XHTML 2.0,尽管应该有一个 XHTML
我正在设计一个订单系统,状态设计模式似乎很合适,因为订单可以更改其状态,从而更改订单允许的功能。下面是我的基本类图: 我不喜欢这种方法,因为客户端无法查看某个方法是否受支持并且违反了里氏原则。我在下面
我正在考虑使用图形数据库来存储 IFC数据。理想情况下,数据库应该提供一种方法来定义 IFC 架构中定义的所有规则类型。但是,我不认为有任何这样的数据库,因为 IFC 中的某些规则类型非常复杂并且需要
我所在的组织必须满足 FISMA 对启用 FIPS 的系统的要求。我正在尝试做的一件事是为我们的密码实现哈希算法。我对此有很多选择:SHA-2、MD5、bcrypt(使用 Blowfish)、RIPE
我正在尝试实现我的自定义 CoreData Carpark 实体以符合 MKAnnotation,就像我们如何使 class 对象符合 >MKAnnotation. 我根据以下帖子调整了我的实现:th
我在 project-Swift.h 文件中收到名为“CBCentralManagerDelegate”的 No 类型或协议(protocol)。不知道我在这里哪里出错了。我认为这与 swift.h
我正在尝试读取之前写入 NVM 闪存的变量的值。 我的代码是: uintptr_t address = getAddress(); //[MISRA C++ Rule 5-2-8] cast from
所以我有这个练习要解决。我必须创建第一个。一个名为 Printable 的接口(interface),它有一个 put() 方法,该方法将接受实现 Comparable 的对象。 完成 interfa
我的问题涉及 IEEE 754 单精度数字。假设我有一个结构: typedef struct __ieee754 { int sign; int exponent; int mant
我需要使用 map,键为 uint32_t,值为 Meshes。我希望将网格布局在连续的内存中以 boost 性能,因为它们将经常被连续访问。 我想知道有哪些内存分配器库可以提供以下内容; 分配给连续
在处理小对象时,有哪些分配器可用于 STL。我已经尝试过使用 Boost 的池分配器,但没有得到任何性能提升(实际上,在某些情况下性能下降相当大)。 最佳答案 你没有说你使用的是什么编译器,但它可能带
我想做什么 我有一种划分事物的方法。此方法不会对数组进行完全排序;它只是简单地对数组进行分区,以便一侧的所有元素(某些预先确定的“中心”或“中点值”——但它不必导致均匀拆分)小于“中心”和另一侧的所有
假设我需要开发一个 REST 银行应用程序允许创建/销毁银行账户以及对帐户进行以下操作:withdraw/credit/getBalance。 创建帐户 PUT/银行/约翰 这里我使用 PUT 而不是
假设我有一个 struct 符合我的模型的 Equatable,如下所示: struct Model: Equatable { var a: Int = 0 var b: String
我目前正在研究 Decodable、Encodable 和 friend ,试图理解它背后的“魔法”。 以下是我发现不寻常的一件事: class Person: Decodable { var n
在 Swift 书中,枚举的例子很好用 enum CompassPoint: String { case north, south, east, west } var northCom = C
我是一名优秀的程序员,十分优秀!