簡體   English   中英

嘗試以自己的using語句訪問MemoryStream時,MemoryStream拋出ObjectDisposedException

[英]MemoryStream throws ObjectDisposedException when trying to access it in its own using statement

我正在嘗試使用流在加載時逐步顯示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.

在最后一個using語句的末尾(在while循環之后)使用Console.WriteLine之后,我發現該代碼似乎在拋出該異常之前在循環中運行了兩次。

the using statement that the stream is declared in. I also don't understand why it worked the other day and doesn't now. 我不明白為什么代碼聲明了該流的using語句中明顯發生時為什么要嘗試訪問封閉的流。我也不明白為什么它在前一天起作用了,但現在不起作用。 大部分代碼都來自這里 ,因此我的方法的其余部分可以在這里找到。 除了一些變量名更改和其他一些小的更改外,我的沒有什么不同。 誰能幫忙解決此問題?

編輯:我的_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
        }));
    }
}

正如我所懷疑的,這是因為您在ProgressChanged處理程序中濫用了MemoryStream

這行:

using (MemoryStream stream = e.UserState as MemoryStream)

正在獲取傳遞給ProgressChanged()的流對象,稍后將在委托中對其進行Dispose 但這您想知道如何將其放置在DoWork方法中的流對象相同

該流不“屬於” ProgressChanged處理程序。 它不應該處理它。

這有些微妙,但是在鏈接的問題中,傳入流唯一要做的就是訪問其ToArray方法。 您還需要注意這一點,因為ProgressChanged (和Dispatcher.BeginInvoke )是異步的,因此您可以輕松地在此處理程序中處理已經處置的對象(但是ToArray可以安全地調用處置的MemoryStream

您還可以考慮從DoWork方法內部的MemoryStream提取byte[]數組,並使狀態成為通過狀態,而不是MemoryStream 這樣一來,現在以及以后對該代碼進行的任何修改都將更不容易被濫用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM