多个 using 声明抛出“IOException”,但语句在写入文件时不会

Exp*_*sam 2 c# using-statement

using声明刚刚被引入,C# 8.0但它们的行为与using块不同,或者我认为。

以下嵌套using块工作正常:

using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey))
using (var file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
    resource?.CopyTo(file);
}
Run Code Online (Sandbox Code Playgroud)

但是当我转换using为如下声明时,我得到一个IOException表示该文件正在被另一个进程使用的信息:

using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
resource?.CopyTo(file);
Run Code Online (Sandbox Code Playgroud)

我想了解有什么不同以及如何\何时使用新using声明?

Cod*_*ack 5

两者 using 声明在解析范围的方式上有所不同。Old Using 用于使用花括号定义自己的范围,

using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
using (var file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
    resource?.CopyTo(file);
}
Run Code Online (Sandbox Code Playgroud)

在这里,资源和文件都将在找到右大括号的那一刻被处理。

有了,新的声明如果你没有像上面那样定义一个范围,它会自动附加到最近的范围,

void certainMethod()
{
   using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
   using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
   resource?.CopyTo(file);
}
Run Code Online (Sandbox Code Playgroud)

这里当方法调用certainMethod结束时,将调用资源和文件的 Dispose。

编辑:对于您的情况,如果您的代码正在执行此操作,则应该没有任何问题,但是如果有两个这样的块,第一个会起作用,但第二个会失败,例如,

 void certainMethod()
    {
       using var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(serviceKey);
       using var file = new FileStream(path, FileMode.Create, FileAccess.Write);
       resource?.CopyTo(file);
       using var oneMoreFile = new FileStream(path, FileMode.Create, FileAccess.Write);
       //This will fail
       resource?.CopyTo(oneMoreFile );

    }
Run Code Online (Sandbox Code Playgroud)