Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在停止下载后我的内存使用量会激增?_C#_Windows Phone 7_Memory Management_Httpwebrequest - Fatal编程技术网

C# 为什么在停止下载后我的内存使用量会激增?

C# 为什么在停止下载后我的内存使用量会激增?,c#,windows-phone-7,memory-management,httpwebrequest,C#,Windows Phone 7,Memory Management,Httpwebrequest,我的程序可以下载5MB到100MB大小的mp3文件,内存“泄漏”大小就是下载的大小。单击暂停或取消下载的按钮后,内存使用量开始逐渐增加。这些额外的内存在积累完[filesize]字节的内存后会自动增加,但我不知道是什么导致了它,也不知道如何停止它 当我跳过/取消下载时,我会更改它检查的状态,以便它退出下载循环并从HttpWebResponse.GetResponseStream处理流 然后,内存使用率逐渐上升,例如,对于20MB的下载,它将上升20MB(如果我在下载中途暂停它,这并不重要)。它以

我的程序可以下载5MB到100MB大小的mp3文件,内存“泄漏”大小就是下载的大小。单击暂停或取消下载的按钮后,内存使用量开始逐渐增加。这些额外的内存在积累完[filesize]字节的内存后会自动增加,但我不知道是什么导致了它,也不知道如何停止它

当我跳过/取消下载时,我会更改它检查的状态,以便它退出下载循环并从HttpWebResponse.GetResponseStream处理流

然后,内存使用率逐渐上升,例如,对于20MB的下载,它将上升20MB(如果我在下载中途暂停它,这并不重要)。它以大约从互联网下载文件所需的速度攀升。当它达到这个数量时,如果下载没有从暂停中恢复(如果我取消了下载,它会在到达该点后立即返回)。当我点击下载上的resume时,下载会自动重新启动,一旦它再次开始获取数据,内存使用就会立即下降到正常水平。然而,无论哪种方式,它都不会消除泄漏,直到它达到最高点

我已经尝试过明确地处理所有相关的事情,包括httpwebresponse,但它没有改变任何事情。似乎有什么东西没有被关闭,或者有什么东西保留了一个流的引用,这使得它在被忽略时积累并存储在内存中。。?我不知道该怎么做,还有什么能给我线索。我希望有一个资源监视器能告诉我什么样的内容占用了所有的内存。感谢您的帮助

下面是我正在使用的代码,尽可能完整地保存它,而不会有太多混乱:

public void Download()
{
    while( paused )
    {
        Thread.Sleep( 1000 );
    }

    if( canceled )
        // signal end of download
    else
    {
        // Checking, rechecking, if/else/etc. In short, this:
        Enabled = true;
        var request = (HttpWebRequest)WebRequest.Create( url );
        request.AllowReadStreamBuffering = false;

        if( m_bytesCurrentlyDownloaded != 0 )
        {
            request.Headers["Range"] = string.Format( "bytes={0}-{1}",
                m_bytesCurrentlyDownloaded.ToString(),
                Filesize - 1 );
        }
        request.BeginGetResponse( new AsyncCallback( DownloadCallback ), request );
    }
}


private void DownloadCallback(IAsyncResult result)
{
    var request = (HttpWebRequest)result.AsyncState;

    HttpWebResponse response;
    try
    {
        response = (HttpWebResponse)request.EndGetResponse( result );
    }
    catch( WebException e )
    {
        response = (HttpWebResponse)e.Response;
    }

    if( response.StatusCode == HttpStatusCode.OK ||
        response.StatusCode == HttpStatusCode.PartialContent )
    {
        FileMode openMode = (m_bytesCurrentlyDownloaded == 0) ? FileMode.OpenOrCreate : FileMode.Append;

        using( var stream = response.GetResponseStream() )
        using( var appStorage = IsolatedStorageFile.GetUserStoreForApplication() )
        using( var file = new IsolatedStorageFileStream( m_incompleteFilename, openMode, FileAccess.Write, appStorage ) )
        {
            byte[] chunk = new byte[chunkSize];
            int readLength = 0;

            do
            {
                if( paused || canceled )
                    readLength = 0;
                else
                {
                    readLength = stream.Read( chunk, 0, chunkSize );

                    if( readLength != 0 )
                    {
                        file.Write( chunk, 0, readLength );
                        m_bytesCurrentlyDownloaded = (int)file.Length;
                    }
                }
            } while( readLength != 0 );

            chunk = null;
        }
        if( m_bytesCurrentlyDownloaded < Filesize ) // got paused, or connection drop
        {
            NeedWaitForNetwork(); // waits only if it needs to
            Download();
        }
        else
            FinishDownload();
    }
}
publicsvoid下载()
{
while(暂停)
{
睡眠(1000);
}
如果(取消)
//下载结束信号
其他的
{
//检查、重新检查、if/else/等简言之,这:
启用=真;
var request=(HttpWebRequest)WebRequest.Create(url);
request.AllowReadStreamBuffering=false;
如果(m_字节当前下载!=0)
{
request.Headers[“Range”]=string.Format(“bytes={0}-{1}”,
m_bytesCurrentlyDownloaded.ToString(),
文件大小-1);
}
BeginGetResponse(新的AsyncCallback(DownloadCallback),request);
}
}
私有void下载回调(IAsyncResult结果)
{
var request=(HttpWebRequest)result.AsyncState;
HttpWebResponse;
尝试
{
response=(HttpWebResponse)request.EndGetResponse(result);
}
捕获(WebE例外)
{
响应=(HttpWebResponse)e.response;
}
如果(response.StatusCode==HttpStatusCode.OK||
response.StatusCode==HttpStatusCode.PartialContent)
{
FileMode openMode=(m_bytesCurrentlyDownloaded==0)?FileMode.openor创建:FileMode.Append;
使用(var stream=response.GetResponseStream())
使用(var appStorage=IsolatedStorageFile.GetUserStoreForApplication())
使用(var file=new-IsolatedStorageFileStream(m_incompleteFilename,openMode,FileAccess.Write,appStorage))
{
byte[]chunk=新字节[chunkSize];
int readLength=0;
做
{
如果(暂停| |取消)
readLength=0;
其他的
{
readLength=stream.Read(chunk,0,chunkSize);
if(readLength!=0)
{
Write(chunk,0,readLength);
m_bytesCurrentlyDownloaded=(int)file.Length;
}
}
}while(readLength!=0);
chunk=null;
}
如果(m_bytesCurrentlyDownloaded
这让我想起了这件事:对我来说,这听起来像是一个堆栈泄漏。线成堆。总是感觉像是一个我无法控制的线程,正在积累所有的内存,怀疑可能是属于HttpWebRequest/Response的某个线程

这对我也有帮助:他正在做一件类似的事情,当他停止下载时,他会直接中止他制作的下载线程。那个.Abort()调用敲响了警钟,我查看了HttpWebRequest.Abort()

了解昨天的活动也有帮助。因此,现在我的代码添加了以下内容:

已将成员添加到我的downloader类:

private ManualResetEvent downloadBreakoutEvent = new ManualResetEvent( false );
在Download()内部,而不仅仅是BeginGetResponse行

downloadBreakoutEvent.Reset();
request.BeginGetResponse( new AsyncCallback( DownloadCallback ), request );
downloadBreakoutEvent.WaitOne();

if( canceled || paused )
{
    request.Abort();
}
在DownloadCallback()的最底部


我一次又一次地暂停/恢复,一次又一次地取消并重新启动,不管怎样,没有内存泄漏

不读取bytesToRead,只读取4096字节。这样就无法获得大型阵列。避免使用BinaryReader,这一点都没有帮助。使用自己的4096字节数组直接从响应流读取。这样你就不会不断地创建新的阵列了。谢谢Hans,这样做更有意义。这部分代码是我第一次开始这个项目时保留的(对C#和所有人来说都是新的),我只是复制粘贴了其他人的代码。我将在几分钟内使用重构代码进行编辑,除非反复创建该数组是问题所在……不幸的是,更改并没有解决内存问题。事实上,这让事情变得更糟了——现在它在恢复后并没有造成内存泄漏。我一定是在做一些非常有趣的事情…不管它变得更糟,似乎它无法删除自己,直到加载完20MB或其他什么,我仍然在看着数字在我恢复之后攀升。
downloadBreakoutEvent.Set();