尝试在自己的using语句中访问时,MemoryStream会抛出ObjectDisposedException

问题描述 投票:0回答:1

我正在尝试使用流来加载时逐步显示jpeg。这曾经工作正常,但今天早上我尝试运行我的代码,现在没有图像可以加载,因为这个错误。相关代码如下:

using (WebClient wc = new WebClient())
using (Stream streamRemote = wc.OpenRead(url))
using (Stream streamLocal = new MemoryStream((int)fileSize))
{
    int byteSize = 0;
    byte[] buffer = new byte[fileSize];

    while ((byteSize = streamRemote.Read(buffer, 0, buffer.Length)) > 0)
    {
        streamLocal.Write(buffer, 0, byteSize); // Error is here.
        bytesDownloaded += byteSize;

        int progressPercentage = (int)(bytesDownloaded / buffer.Length) * 100;

        if (progressPercentage % 10 == 0)
        {
            imageLoader.ReportProgress(progressPercentage, streamLocal);
        }
    }
}

// Exception thrown: 'System.ObjectDisposedException' in mscorlib.dll
// An exception of type 'System.ObjectDisposedException' occurred in mscorlib.dll but was not handled in user code
// Cannot access a closed Stream.

在最终使用语句结束后使用Console.WriteLine(在while循环之后),我发现代码似乎在抛出异常之前经过了几次循环。

我不明白为什么当代码明确发生在声明流声明的using语句中时,我会尝试访问一个封闭的流。我也不明白为什么它在前几天工作而现在没有。大多数代码来自here,所以我的方法的其余部分可以在那里找到。除了一些变量名称更改和其他小变化之外,我的差别不大。谁能帮忙解决这个问题?

编辑:我的_ProgressChanged事件:

private void ImageLoader_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (!fileFailed)
    {
        Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        new Action(delegate ()
        {
            try
            {
                using (MemoryStream stream = e.UserState as MemoryStream)
                {
                    BitmapImage bmp = new BitmapImage();
                    bmp.BeginInit();
                    using (MemoryStream ms = new MemoryStream(stream.ToArray())) bmp.StreamSource = ms;
                    bmp.EndInit();

                    img_CurrentImage.Source = bmp;
                }
            }
            // A few catch statements here - none of the exceptions here are being thrown anyway so I'll omit the catch statements
        }));
    }
}
c# stream using memorystream objectdisposedexception
1个回答
4
投票

我怀疑,这是因为你在你的MemoryStream处理程序中滥用ProgressChanged

这一行:

using (MemoryStream stream = e.UserState as MemoryStream)

正在获取传递给ProgressChanged()的流对象,稍后将在它的委托Dispose中。但这是完全相同的流对象,你想知道它是如何在你的DoWork方法中处理的。

该流不属于ProgressChanged处理程序。不应该处理它。

它有点微妙,但在链接的问题中,传入流中唯一做的就是访问它的ToArray方法。你需要谨慎做到这一点,因为ProgressChanged(和Dispatcher.BeginInvoke)是异步的,你可以很容易地处理这个处理程序中已经处理好的对象(但ToArray可以安全地调用处置的MemoryStreams)

您也可以考虑从byte[]方法中的MemoryStream中提取DoWork数组,并使其成为通过状态而不是MemoryStream。这将使它现在和将来对此代码的任何编辑都不太容易被滥用。

© www.soinside.com 2019 - 2024. All rights reserved.