我通过Silverlight上传大文件并实现了分块功能。它工作正常,但是,如果我连续上传三个大(500MB)文件,我仍然会出现内存异常。下面是我的代码,你能发现任何遗漏的东西吗?Silverlight 3在分块文件上传时出现内存异常
const int _ReadSize = 2097152;
byte[] _Buffer = new byte[_ReadSize];
/// <summary>
/// This method will do the initial read and write and send off the first chunk of data.
/// This is where the filestream is opened from the file info.
/// It also passes a set of parameters to the next call. These are:
/// * bytesRead - the number of bytes that was actually read from the file with stream.Read
/// * stream - This is the filestream
/// * offset - This is the updated offset that has been moved to the position in the stream we are currently at
/// </summary>
void DoWork()
{
FileStream stream = _SelectedFile.OpenRead();
ServerAvailable = false;
bool startRead = true;
int bytesRead = 0;
bytesRead = stream.Read(_Buffer, 0, _ReadSize);
int offset = bytesRead;
List<object> args = new List<object>();
args.Add(bytesRead);
args.Add(stream);
args.Add(offset);
IDataManipulationService client = new DataManipulationServiceClient();
client.BeginUploadLargeFile(_Buffer, (int)_SelectedFile.Length, FileName, startRead, offset - bytesRead, bytesRead, FinishedUploadPiece, args);
}
/// <summary>
/// This method is called once the previous call to the web server has been completed.
/// It will read the next chunk of the file and send that through to the web server next.
/// If 0 bytes were read from the previous read on the stream; it will do the following:
/// - Close the file stream
/// - Dispose the file stream
/// - set the FileInfo to null
/// - Reset the FileSize, UploadProgress and FileName variables to default values
/// - Make the buttons available for use
/// </summary>
/// <param name="result">The result contains the information about the outcome of the previous call. This also contains the args parameter sent through with the previous call.</param>
void FinishedUploadPiece(IAsyncResult result)
{
if (result.IsCompleted)
{
List<object> args = (List<object>)result.AsyncState;
int bytesRead = (int)args[0];
FileStream stream = (FileStream)args[1];
int offset = (int)args[2];
if (bytesRead != 0)
{
UploadProgress += bytesRead;
if (UploadProgress == FileSize)
{
FileSize = 0;
UploadProgress = 0;
FileName = String.Empty;
ServerAvailable = true;
stream.Close();
stream.Dispose();
_SelectedFile = null;
}
else
{
bytesRead = stream.Read(_Buffer, 0, _ReadSize);
offset += bytesRead;
args = new List<object>();
args.Add(bytesRead);
args.Add(stream);
args.Add(offset);
IDataManipulationService client = new DataManipulationServiceClient();
client.BeginUploadLargeFile(_Buffer, (int)_SelectedFile.Length, FileName, false, offset - bytesRead, bytesRead, FinishedUploadPiece, args);
}
}
}
}
为了澄清一些东西: _SelectedFile是FileInfo的类型,并创建服务器每次我想通过发送数据,但也试图有一个全球性的注入连接一个新的连接。
确保您处理_every_流或其他任何一次性的对象。正如我看到的,只有在'result.IsCompleted'成立的情况下才会处理流。但是在场景中,它是错误的,流不会被丢弃。顺便说一句,你可以调用'Close'或'Dispose()'。无需两次使用它们。 – Leri
首先,你没有处理文件流,也没有可能导致内存泄漏的流代码异常处理。 – Romoku
感谢您的回复。我做了PLB和Romoku的建议,并添加了异常处理和处理结果的代码,如果它不是'result.IsCompleted',但我仍然有问题。 – Johannes