简体   繁体   English

如何在FileStream.Close / Dispose上处理IOException

[英]How to handle IOException on FileStream.Close/Dispose

Based on documentation FileStream.Close/Dispose can throw an IOException, with other streams/services I have switched away from 'using' due to the situation of exceptions on close leaving the connection open and essentially orphaned in favor of the following model: this decision is supported by MSDN Suggested Practice 根据文档,FileStream.Close / Dispose可能引发IOException,由于关闭时会出现异常情况,我关闭了其他流/服务,从而使连接保持打开状态,并且基本上孤立了此模型,从而支持以下模型:受MSDN建议实践支持

try 
{
  //do work
  handler.Close(); //or equivalent
}
catch(IOException)
{
  handler.Abort();  
}
finally
{
  handler.Dispose(); 
}

The issue here is that on FileStream Close is essentially Dispose, and there is no Abort. 这里的问题是,在FileStream上关闭实际上是Dispose,并且没有中止。 This is in a project that does not have access to .net 4.5 so manually triggering the task cancellation on ReadAsync is not available, so what is the best strategy for handling this, or can you explain why this is not actually a concern unlike a connection to SQL/WCF/etc if that is actually the case? 这是在无法访问.net 4.5的项目中,因此无法在ReadAsync上手动触发任务取消,因此处理此问题的最佳策略是什么,或者您能否解释一下为什么实际上不像连接那样担心?到SQL / WCF / etc,如果真的是这样?

The use case in this scenario is user image upload to a Silverlight control. 在这种情况下,用例是将用户图像上传到Silverlight控件。 I am currently using 'using' as it is more concise/readable than the t/c/f block which, in this situation, does not add any value that I can find. 我目前正在使用“使用”,因为它比t / c / f块更简洁/可读,在这种情况下,t / c / f块不会添加我可以找到的任何值。

Until today I didn't know that FileStream.Dispose/Close could throw an IOException, but it turns out it can. 直到今天,我还不知道FileStream.Dispose / Close会抛出IOException,但事实证明可以。 Not that I thought the OP was wrong. 并不是说我以为OP是错误的。

else {
    // ERROR_INVALID_PARAMETER may be returned for writes
    // where the position is too large (ie, writing at Int64.MaxValue 
    // on Win9x) OR for synchronous writes to a handle opened 
    // asynchronously.
    if (hr == ERROR_INVALID_PARAMETER)
        throw new IOException(Environment.GetResourceString("IO.IO_FileTooLongOrHandleNotSync"));
    __Error.WinIOError(hr, String.Empty);
}

The above code was taken from FileStream.cs , the method is Write. 上面的代码来自FileStream.cs ,方法为Write。

There are two cases where an IOException will be thrown during Dispose/Close. 在两种情况下,在Dispose / Close期间将引发IOException。 One will be using a position that is greater than Int64.maxValue on a Win9x system. 一个人将在Win9x系统上使用大于Int64.maxValue的位置。 The second is trying to write synchronously to a handle that was opened asynchronously. 第二个尝试同步写入异步打开的句柄。

I really doubt that you're using a Win9x system so that really isn't a consideration. 我真的怀疑您使用的是Win9x系统,因此确实不是要考虑的问题。 The second one is a little more likely to crop up, although it is very unlikely from what I can tell and should be caught in development. 第二个似乎更有可能长大,尽管据我所知这不太可能,应该将其纳入发展之中。

I would say you are fine using a "using" statement in this case. 我想说在这种情况下使用“ using”语句是可以的。 The IOException is an edge that is unlikely to pop up and if it does it will likely be during development. IOException是一个不太可能弹出的边缘,如果出现,则很可能会在开发期间出现。

Unless of course you're developing on a Windows 98 machine, in that case you should just quit. 除非您当然是在Windows 98计算机上进行开发,否则您应该退出。

Side note: This answer is based on my interpretation of the code in FileStream.cs. 旁注:该答案基于我对FileStream.cs中代码的解释。 If I made any incorrect assumptions, please let me know and I'll adjust my answer appropriately. 如果我做出任何错误的假设,请让我知道,我将适当地调整答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM