argumentoutorange异常,当尝试使用ReadAsync报告读取文件的进度时



我正在尝试使用进度条读取文件并显示更新。我一直得到这个错误读取文件的最后一部分:

系统。ArgumentOutOfRangeException: '7340032'的值对'Value'无效。"值"应该在"最小值"one_answers"最大值"之间。参数名称:值'

在此位置

progressBar.Value = position;

这是我的全部代码


private async void readFileWithProgressBar(
string fileToRead, ProgressBar progressBar)
{
var fileSize = (int)(new FileInfo(fileToRead).Length);
// Set the maximum value of the progress bar to the file size
progressBar.Maximum = fileSize;
// Now read the file with FileStream functions
int position = 0;
int blockSize = 1024 * 1024; // Read 1 megabyte at a time
byte[] allData = new byte[fileSize]; 
using (var fs = new FileStream(fileToRead, FileMode.Open))
{
var bytesLeft = fileSize;
while (bytesLeft > 0)
{
await fs.ReadAsync(
allData, position, Math.Min((int)bytesLeft, blockSize));
// Advance the read position
position += blockSize;
// Update the progress bar
progressBar.Value = position; //ERROR IS HERE
bytesLeft -= blockSize;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
readFileWithProgressBar(@"<path>test.txt",progressBar1);
}

我的代码几乎执行到最后,但突然停止并给出上面的错误。

问题是您使用的是blockSize而不是读取的字节数。假设您有一个15字节的文件,并且将blockSize设置为10

迭代将像这样进行:

  1. 设置最大值为15,位置为0
  2. 从文件中读取最多10个字节
  3. 给位置增加10(新值:10)。
  4. 设置进度= 10
  5. 从文件中读取最多10个字节。我们只剩下5个字节要读,所以我们实际上只会得到5个字节。
  6. 位置增加10(新值:20)。
  7. 设置进度= 20.

可以看到,新的Progress值(20)大于Maximum值(15)。

幸运的是,await ReadAsync为您提供了读取的字节数,因此您可以存储它并将其应用于位置。把你的代码改成这样:

int bytesRead = await fs.ReadAsync(allData, position, Math.Min((int)bytesLeft, blockSize));
// Advance the read position
position += bytesRead;
progressBar.Value = position;

除了在文件末尾的这种情况外,一些Stream实现可能由于其他原因读取比预期少的字节。有时注意实际读取了多少字节是很重要的,而不是注意请求读取了多少字节。

最新更新