【问题标题】:Is there a .NET 4.5 equivalent to: Storagefile.Openasync是否有 .NET 4.5 等效于:Storagefile.Openasync
【发布时间】:2014-08-26 19:37:07
【问题描述】:

我爱上了 async 和 await,但是我不知道如何在不使用 Task.Run 的情况下等待文件打开。似乎有一个API in WRT。 .NET 4.5 等效项在哪里?我问是因为如果我正在访问远程机器上的 UNC 共享,如果机器因某种原因关闭或没有响应网络请求,这可能会阻塞很长时间。这似乎是一个很大的网站。

using (FileStream stream = await Task.Run(() => new FileStream(@"c:\temp\text.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, 4096, true)))
{
  byte[] bytesToRead = new byte[stream.Length];    
  await stream.ReadAsync(bytesToRead, 0, bytesToRead.Length).ConfigureAwait(false);
  return bytesToRead;
}

【问题讨论】:

  • 调用new FileStream 不会开始从流中读取,没有理由使用Task.Run。您的代码在到达await stream.ReadAsync 时已经是异步的,它实际上开始从流中读取。
  • 我不同意:Stopwatch sw = Stopwatch.StartNew(); try { new FileStream(@"\\10.1.1.2\c$\test", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read, 4096, true); } catch (Exception ee) { Trace.WriteLine(ee.Message); } finally { Trace.WriteLine(sw.Elapsed); } 找不到网络路径。 00:00:38.5445538 这需要 30 秒。在引擎盖下它最终会调用:[link]referencesource.microsoft.com/#mscorlib/microsoft/win32/… 这是同步的。
  • 我刚刚尝试打开一个 4GB 文件的句柄,我花了 00:00:00.0004030。我这样称呼它:var fs = new FileStream(@"C:\HugeFile.zip", FileMode.Open, FileAccess.Read, FileShare.Read);
  • 那个文件是本地的。尝试通过我在示例中不存在的 unc 打开网络共享。这将需要很长时间。
  • 您确定花费的时间是打开手柄所消耗的吗?我认为它是罪魁祸首的网络线。

标签: c# .net async-await


【解决方案1】:

不幸的是,即使文件打开在设备驱动程序级别是异步的,也没有用于异步文件打开的 Win32 API。这就是为什么没有 .NET 等价物的原因。我不确定,但我怀疑 WinRT API 通过将异步操作排队到线程池来伪造异步操作。

因此,最好的解决方案是执行类似的解决方法:使用Task.Run。不过,我会将所有 FileStream 代码包装在 Task.Run 中。

【讨论】:

  • CreateFileFILE_FLAG_OVERLAPPED 不会异步打开文件的句柄?
  • @YuvalItzchakov:不,它(同步)打开启用异步操作的文件句柄。
  • 只是在谷歌搜索后添加更多信息。 “我将此线程作为功能建议发送给 I/O 管理人员。能够无延迟地打开网络上的文件可能很有用,尽管很难将尚不存在的文件与完成端口相关联,所以如果它发生的话,它可能最终会成为一个事件驱动的过程。” link
  • (在没有异步文件句柄的情况下)“再说一次,它一定不会太糟糕,因为我们已经相处得很好,没有它这么长时间,而且不仅仅是在 Windows 上。” ,哈哈。
【解决方案2】:

我在不使用 Task.Run 的情况下将 https://github.com/tejacques/AsyncBridge 用于 async 方法有很好的经验,虽然在语法上看起来有些相似,但更安全。

【讨论】:

  • 虽然看起来很不错,但它并不能解决在打开文件时需要阻塞线程的问题。 IO 不需要阻塞线程周期。它们提供这些用于读取和写入文件但不打开的调用。看起来很傻。
  • 我看不出这有什么帮助:AsyncBridge 似乎是关于同步等待异步方法,这里的问题是没有异步替代可能需要很长时间的操作时间。
  • 它有一个异步触发和忘记 api...猜它没有记录,哦,好吧。
猜你喜欢
  • 2012-09-03
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多