- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
由于我必须在我的应用程序中进行大量文件 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); });
}
考虑范式 "Don’t use Task.Run in Libraries" , 我想知道是否有更好的实现或者我应该回退到同步代码?
非常感谢!
编辑:
最佳答案
如果你必须这样做,我会这样写方法(注意:我欣然同意这正是 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); });
}
这稍微清理了代码并消除了过多的上下文/线程切换。
在基于 GUI 的程序的上下文中,使用这些包装器似乎很好。我认为只要您不创建具有并行同步和异步 API 的全新库(如所引用的文章中所述),这并不可怕。
但对我来说,更大的问题是这些操作中没有一个可能需要足够长的时间来证明首先使它们异步。 IE。您从 UI 线程在 Task
中运行内容的通常原因是您的 UI 线程不能在操作完成时等待。但是在这里,对于这些操作中的每一个,将操作发送到线程池,然后在完成后继续执行的操作,可能会像操作本身一样增加程序的性能开销。
正是出于那个的原因,我建议完全不要使用这些方法的异步版本。只需直接从 UI 调用 Create()
、Delete()
和 Move()
方法。
(注意:上述情况的一个异常(exception)是如果处理网络共享或不同的卷,其中 Move()
涉及实际复制数据。所以即使在那里,它也是一个巨大的“它取决于”。同样,虽然 Delete()
和 Create()
通常即使在网络上也很快,但如果操作实际上将要失败,它们可能需要一段时间。您可能实际上有一个很好的用例来在那里异步运行操作。
关于c# - 如何实现异步 File.Delete/Create/Move?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29013958/
C++ 中的标准“映射”容器允许您插入右值: T x; std::map m; // m[1]; // populate "1" auto it = m.insert(std::make_pair(
我们知道 std::move does not actually move anything .它只是将左值引用 (&) 转换为右值引用 (&&)。 那么在下面的例子中,拷贝构造函数是如何被调用的呢?
http://en.cppreference.com/w/cpp/language/rule_of_three 几个月前我开始使用 c++11并观看了五人规则。 所以..我开始将复制构造函数/复制赋值
这个问题在这里已经有了答案: In what scenarios should I expect to explicitly need to implement a move constructor
我有一个类似于下面的对象,我正在尝试为它实现一个 move 构造函数,这样你就可以为 std::vector 插入一个. struct Mesh { std::vector vPoint
这个问题在这里已经有了答案: How to create an std::function from a move-capturing lambda expression? (3 个回答) 关闭7年前
我有一个源文件,我正在使用它 move 到一个存档目录 关闭。 move (srcfile,dstdir) 但是当存档目标目录中已经存在相同的文件时,它会抛出一个错误,指出无法 move 文件已经存在
这应该有效,但无效并给出以下错误(如下)。 我读过几篇关于 stackoverflow 的帖子 here和 here但在这种情况下似乎没有一个好的答案。我真的希望我只是错过了一些愚蠢的东西,我已经在这
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我似乎无法弄清楚为什么会这样。当我运行以下代码时: $uref = APACHE_ROOT . UPLOAD_PATH . $applicant . "_ref_{$email}_{$year}";
我的表格行可以上下 move ,但我的问题是数据表行取代了表格标题(第一行)。 我想要一个固定的第一行,这样当您单击向上箭头时,您就不会向上 move 该行来替换标题。 我尝试了一些条件逻辑来检查当前
正如我在Move constructor/operator=中询问的那样,过了一段时间,我同意并接受了这个问题的正确答案,我只是在想,是否有类似“移动析构函数” 这样的东西会在每次移动的对象上调用会有
如果我有一个像这样的 C 类: class C { std::string s; public: C(std::string& s) : s(s) {} C(std::str
我是 C++11 的新手,发现 move 语义和复制省略非常适合编写优雅高效的代码。不过我有一些问题想请教。这里我写了一个模板类 matrix.hpp 并用它来测试 move 语义的行为。 #incl
我在我们的项目中遇到了这样的代码: class A { public: A(A&& obj): valid_(false), data_(obj.data_) {} //... void
move 语义在这个例子中是如何工作的: struct test { int ii[10]; int i; }; test f() { test a; std::cou
假设我有一个类型为 A 的对象 a。 如果我想将其 move 到函数foo(A)。 一个选择是执行 foo(std::move(a)),这将调用 move 构造函数。 但是,假设我正在使用一个我无法控
我用 move 复制构造函数和 move 复制赋值运算符创建了一个简单的应用程序,并且在它们中的每一个上我都做了一个 cout 语句来告诉我,它们正在执行。但是在执行过程中,我没有看到 move 复制
相关问题: Why this move constructor is not called wtih rvalue temporary? [duplicate] Move Constructor vs
我正在努力研究 move 构造函数,并希望通过这个问题获得更多见解。这是一个简单的类。 class A { private: vector Bs; public: /* ..
我是一名优秀的程序员,十分优秀!