我正在做一個文件流的副本異步操作。我注意到,如果在操作過程中發生錯誤,我不會收到任何錯誤異常。對網絡故障流CopyAsync和WriteAsync
用大文件測試,在複製操作過程中,突然關閉網絡連接。
經過一段時間後,測試結束。
我希望能夠捕獲複製操作期間發生的任何錯誤。
我在下面複製代碼示例,只是要求一些幫助。
BR亞歷
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
using static System.Console;
namespace CopyAsync
{
[TestClass]
public class UnitTest
{
public int BufferSize = 10;
[TestMethod]
public void CopyFileAsyncSouldCopyFile()
{
BufferSize = 10;
const string source = @"..\..\UnitTest.cs";
var destination = Path.GetRandomFileName();
WriteLine($"Start...");
var task = CopyAsync(source, destination, action: (total) => WriteLine($"Copying... {total}"));
var bytes = task.Result;
WriteLine($"Bytes copied... {bytes}");
IsTrue(File.Exists(destination));
AreEqual((new FileInfo(source)).Length, bytes);
File.Delete(destination);
}
[TestMethod]
public void CopyFileAsyncCancelledSouldCancelCopyFile()
{
BufferSize = 10;
const string source = @"..\..\UnitTest.cs";
var destination = Path.GetRandomFileName();
var cts = new CancellationTokenSource();
WriteLine($"Start...");
var task = CopyAsync(source, destination, cts.Token,
(total) =>
{
WriteLine($"Copying... {total}");
if (total > 1677)
return;
cts.Cancel();
WriteLine($"Canceled...");
});
try
{
var bytes = task.Result; // exception WILL BE thrown here
WriteLine($"Bytes copied... {bytes}"); // WON'T BE executed
}
catch (AggregateException ex) when (ex.InnerException.GetType() == typeof(TaskCanceledException))
{
WriteLine($"TaskCanceledException...");
File.Delete(destination);
}
}
[TestMethod]
// Exception not captured
// missed: System.AggregateException: One or more errors occurred. ---> System.IO.IOException: The network path was not found.
public void CopyFileAsyncNetworkErrorShouldFail()
{
const string source = @"..\..\verybigfile.iso";
var destination = Path.GetRandomFileName();
BufferSize = 4096;
WriteLine($"Start...");
var task = CopyAsync(source, destination, action: (total) => WriteLine($"Copying... {total}"));
var bytes = task.Result; // exception WON'T BE thrown here
WriteLine($"Bytes copied... {bytes}"); // WILL BE executed
}
public async Task<int> CopyAsync(string input, string output, CancellationToken token = default(CancellationToken), Action<long> action = null)
{
using (var source = new FileStream(input, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, true))
using (var destination = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None, BufferSize, true))
{
int bytes;
var total = 0;
var buffer = new byte[BufferSize];
while ((bytes = await source.ReadAsync(buffer, 0, buffer.Length, token)) > 0)
{
await destination.WriteAsync(buffer, 0, bytes, token);
total += bytes;
action?.Invoke(total);
}
return total;
}
}
}
}
哪邊是網絡,讀或寫? –
讀取端類似於\\ server \ sharedFolder \ verybigfile.iso, – alhpe
最後一個測試是從UNC路徑(如\\ server \ sharedfolder \ verybigfile.iso)對硬盤進行應對 如果在複製過程中將網絡電纜從桌面,而不是拋出錯誤測試通過。我會喜歡有系統拋出異常 但是,如果您從E:\ verybigfile.iso等可移動設備上覆制,並在複製時刪除筆式驅動器,然後是,則系統會引發異常:System.AggregateException:發生一個或多個錯誤。 ---> System.IO.FileNotFoundException:無法找到指定的文件。這對我來說行爲很好 – alhpe