Skip to content

Regression: ObjectDisposedException in overridden FileStream.Dispose(bool disposing) #82186

@pharring

Description

@pharring

Description

If you have a class derived from FileStream that overrides void Dispose(bool disposing) and accesses the Length property, you'll get an ObjectDisposedException when the stream is disposed asynchronously via IAsyncDisposable.DisposeAsync (await using ...)

Reproduction Steps

using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        await using MyStream file = new(Path.GetTempFileName(), FileMode.Open);
    }
}

class MyStream : FileStream
{
    private bool _isDisposed;

    public MyStream(string path, FileMode mode) : base(path, mode)
    {
    }

    protected override void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            Console.WriteLine("Dispose({0}) called. Length {1}.", disposing, Length);
            _isDisposed = true;
        }

        base.Dispose(disposing);
    }
}

Expected behavior

Dispose(True) called. Length 0.

Actual behavior

Unhandled exception. System.ObjectDisposedException: Cannot access a closed file.
   at System.IO.FileStream.get_Length()
   at MyStream.Dispose(Boolean disposing) in D:\Throwaway\ConsoleApp26\ConsoleApp26\Program.cs:line 25
   at System.IO.FileStream.DisposeAsync()
   at Program.Main(String[] args) in D:\Throwaway\ConsoleApp26\ConsoleApp26\Program.cs:line 9
   at Program.<Main>(String[] args)

Regression?

Worked in .NET Core 3.1, .NET 5 and .NET 6 prior to 6.0.14 release

Known Workarounds

Override DisposeAsync

Configuration

.NET 6.0.14
Windows 11
x64

Other information

This is similar to #82176 (probably has the same root cause), but it demonstrates that the obvious workaround (override Dispose(bool disposing)) isn't sufficient.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions