【问题标题】:StorageFile Async usage in a NON Metro application非 Metro 应用程序中的 StorageFile 异步使用
【发布时间】:2015-03-12 21:15:39
【问题描述】:

我正在尝试在我的类库中创建一个 StorageFile 实例...

var localFolder = ApplicationData.Current.LocalFolder;
StorageFile destinationFile = await localFolder.CreateFileAsync(destination, CreationCollisionOption.GenerateUniqueName);

VS11 没有构建说:'await' 要求类型 'Windows.Foundation.IAsyncOperation' 具有合适的 GetAwaiter 方法。您是否缺少“系统”的 using 指令?

显然,我使用 .net 4.5 作为目标,并且我正在引用 Windows 程序集... 不知道为什么这段代码可以在 MetroStyle 中工作,但不能在类库中构建......如何在类库中创建 Storagefile 的实例?在这个阶段,是否以异步方式创建文件并不重要......

请告诉我你的想法... 斯特里奥

【问题讨论】:

  • 在 Metro 风格中,代码文件顶部是否有额外的 using 语句?

标签: c# windows-8 windows-runtime isolatedstorage async-await


【解决方案1】:

对我有用的是“手动”添加 TargetPlatformVersion

<PropertyGroup>
  <TargetPlatformVersion>8.0</TargetPlatformVersion>
</PropertyGroup>

并在项目组中添加以下内容

<ItemGroup>
  <Reference Include="System.Runtime.WindowsRuntime" />
  <Reference Include="System.Runtime" />
  <Reference Include="Windows" />
</ItemGroup>

然后项目应该可以正常编译了。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。问题是命名空间标头中缺少系统命名空间。我只是在命名空间中包含了 system 并且它工作正常。希望有帮助。

    【讨论】:

      【解决方案3】:

      看起来您正在尝试使用 WinRT 库中的类型,因为 StorageFile class documentation 声明它仅适用于 Metro 并且可以在 Windows.Storage 中找到。

      This blog post 介绍了如何构建它,但它似乎是一个手动过程。它还详细说明了错误的原因:

      使用 await 关键字会导致编译器查找 GetAwaiter 这个接口上的方法。由于 IAsyncOperation 不 定义一个 GetAwaiter 方法,编译器想要寻找一个 扩展方法。

      基本上,看起来你需要添加一个引用:System.Runtime.WindowsRuntime.dll


      请花时间阅读他的博文,但为了清楚起见,我将把重要部分放在这里。


      以下博客内容被毫不客气地抄袭

      首先,在记事本中,我在 EnumDevices.cs 中创建了以下 C# 源代码:

      using System;
      using System.Threading.Tasks;
      using Windows.Devices.Enumeration;
      using Windows.Foundation;
      
      class App {
          static void Main() {
              EnumDevices().Wait();
          }
      
          private static async Task EnumDevices() {
              // To call DeviceInformation.FindAllAsync:
              // Reference Windows.Devices.Enumeration.winmd when building
              // Add the "using Windows.Devices.Enumeration;" directive (as shown above)
              foreach (DeviceInformation di in await DeviceInformation.FindAllAsync()) {
                  Console.WriteLine(di.Name);
              }
          }
      }
      

      其次,我创建了一个 Build.bat 文件,我从开发人员命令提示符运行该文件以构建此代码(这应该是 1 行,但为了便于阅读,我将其包装在这里):

      csc EnumDevices.cs  
      /r:c:\Windows\System32\WinMetadata\Windows.Devices.Enumeration.winmd  
      /r:c:\Windows\System32\WinMetadata\Windows.Foundation.winmd 
      /r:System.Runtime.WindowsRuntime.dll  
      /r:System.Threading.Tasks.dll
      

      然后,在命令提示符下,我只需运行 EnumDevices.exe 即可查看输出。

      【讨论】:

      • 我认为应该指出 Jeffrey Richter 在他的帖子中提到的内容:缺少的程序集是 System.Runtime.WindowsRuntime.dll。
      • 伙计们,感谢您的及时响应...我试图在 Windows 8 上使用 WPF 应用程序的后台下载器(在非 Metro 环境中),但我想这不是一个好主意并且最好使用 BITS.... 但我认为将 interop 与 windowsRuntime 一起使用不是一个好主意...
      • 尝试运行博客中的示例时出现以下错误:numDevices.cs(14,35): error CS4028: 'await' requires that the type 'Windows.Foundation.IAsyncOperation&lt;Windows.Devices.Enumeration.DeviceIn formationCollection&gt;' have a suitable GetAwaiter method. Are you missing a using directive for 'System'?
      • @Hjulle 文件顶部有 using 语句吗? using System;。另外,您是否在相关 C# 版本上运行了足够晚的 VS 版本以获得 await 关键字支持?
      • 是的,我完全复制了这个例子。我假设它支持await 关键字,因为它正在寻找GetAwaiter 方法,而不是抱怨未知关键字或其他东西。但是我没有运行VS,我使用的是.NET 4.5运行时自带的csc编译器。
      【解决方案4】:

      我发帖应该是很久以前的事了 添加引用后:
      System.Runtime.WindowsRuntime.dll
      System.Threading.Tasks.dll

      并在项目文件中定位 Windows 8:

        <PropertyGroup>
          <TargetPlatformVersion>8.0</TargetPlatformVersion>
        </PropertyGroup>
      

      上面提到的例子可以在VS中编译。

      【讨论】:

      • 如果您想问什么,请单独发帖。
      猜你喜欢
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 2012-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多