Я надеюсь, что все в порядке. Это мой первый ответ на StackOverflow.
Да, если размер куска превышает 85000 байт, массив будет размещен в куче больших объектов. Вероятно, вам не хватит памяти не очень быстро, поскольку вы выделяете и освобождаете смежные области памяти одинакового размера, поэтому, когда память заполняется, среда выполнения может поместить новый блок в старую, восстановленную область памяти.
Я бы немного беспокоился о вызове Array.Resize, поскольку он создаст другой массив (см. http://msdn.microsoft.com/en-us/library/1ffy6686(VS.80).aspx).. Это ненужный шаг, если actualLength == Chunksize, как это будет для всех, кроме последнего чанка. Поэтому я бы как минимум предложил:
if (actualLength != chunkSize) Array.Resize(ref buffer, actualLength);
Это должно удалить много выделений. Если actualSize не совпадает с chunkSize, но все еще> 85000, тогда новый массив также будет размещен в куче больших объектов, что может привести к его фрагментации и, возможно, к явным утечкам памяти. Я полагаю, что на самом деле потребуется много времени, чтобы фактически исчерпать память, поскольку утечка будет довольно медленной.
Я думаю, что лучшей реализацией было бы использование некоторого пула буферов для предоставления массивов. Вы могли бы бросить свой собственный (это было бы слишком сложно), но WCF действительно предоставляет один для вас. Я немного переписал твой код, чтобы учесть это:
BufferManager bm = BufferManager.CreateBufferManager(chunkSize * 10, chunkSize);
for (int i = resumeChunk; i < chunks; i++)
{
byte[] buffer = bm.TakeBuffer(chunkSize);
try
{
fileStream.Position = i * chunkSize;
int actualLength = fileStream.Read(buffer, 0, (int)chunkSize);
if (actualLength == 0) break;
//Array.Resize(ref buffer, actualLength);
using (MemoryStream stream = new MemoryStream(buffer))
{
UploadFile(stream, actualLength);
}
}
finally
{
bm.ReturnBuffer(buffer);
}
}
это предполагает, что реализация UploadFile может быть переписана, чтобы взять int для no. байтов для записи.
Надеюсь, это поможет
Джо