Fab*_*abe 13 c# io asynchronous task-parallel-library async-await
由于我必须在我的应用程序中执行大量文件I/O操作,因此我决定异步实现它们.查看MSDN,File.Create,File.Delete和File.Move没有异步对应项.据我所知,原因是不存在用于文件删除,创建或移动的异步Win32实现,所以我最终得到了以下解决方案:
public static Task DeleteAsync(string path)
{
Guard.FileExists(path);
return Task.Run(() => File.Delete(path));
}
public static Task<FileStream> CreateAsync(string path)
{
Guard.IsNotNullOrWhitespace(path);
return Task.Run(() => File.Create(path));
}
public static Task MoveAsync(string sourceFileName, string destFileName)
{
Guard.FileExists(sourceFileName);
Guard.IsNotNullOrWhitespace(destFileName);
return Task.Run(() => { File.Move(sourceFileName, destFileName); });
}
Run Code Online (Sandbox Code Playgroud)
考虑到范例"不要在库中使用Task.Run",我想知道是否有更好的实现或者我应该回退到同步代码?
提前谢谢了!
编辑:
如果你必须这样做,我会写这样的方法(注意:我很同意这正是Stephens Cleary和Toub敦促我们不要这样做的):
public static Task DeleteAsync(string path)
{
Guard.FileExists(path);
return Task.Run(() => { File.Delete(path); });
}
public static Task<FileStream> CreateAsync(string path)
{
Guard.IsNotNullOrWhitespace(path);
return Task.Run(() => File.Create(path));
}
public static Task MoveAsync(string sourceFileName, string destFileName)
{
Guard.FileExists(sourceFileName);
Guard.IsNotNullOrWhitespace(destFileName);
return Task.Run(() => { File.Move(sourceFileName, destFileName); });
}
Run Code Online (Sandbox Code Playgroud)
这样可以清除代码并消除过多的上下文/线程切换.
在基于GUI的程序的上下文中,使用这样的包装器似乎很好.我认为,只要您不创建一个并行的同步和异步API的全新库,如所提到的文章所述,这并不可怕.
但对我来说,更大的问题是这些操作中没有一个可能花费足够长的时间来证明它们首先使它们异步.也就是你在TaskUI线程中运行东西的通常原因是因为你的UI线程在操作完成时无法等待.但是在这里,对于每个操作,将操作发送到线程池,然后在完成后继续操作,可能会为操作本身添加尽可能多的性能开销.
出于这个原因,我建议不要打扰方法的异步版本.只是调用Create(),Delete()以及Move()直接从用户界面的方法.
(注意:上面的一个例外是如果处理网络共享或不同的卷,其中Move()涉及实际复制数据.所以即使在那里,它也是一个巨大的"它取决于".同样,虽然Delete()并且Create()通常会快速甚至超过如果操作实际上会失败,它们可能需要一段时间.实际上你可能有一个很好的用例来异步运行操作).