Роб, спасибо, что предложили помощь и указали на разницу в хешах MD5. Ваш ответ заставил меня задуматься в правильном направлении. Я провел еще целый день, копаясь в этом, но, к счастью (и благодаря вашему замечанию :)), мне наконец удалось решить проблему. Оказалось, что в моем случае было две проблемы:
1) Хэш MD5 : Я заметил, что хеш, который вы вставили в свой ответ, короче того, который я получил, но мне потребовалось некоторое время, чтобы увидеть, что ваш хэш был ровно дважды короче. После некоторых экспериментов я обнаружил, что метод GetMD5HashFromStream () из вашего тестового приложения преобразует хеш 16-байтовый , сгенерированный MD5CryptoServiceProvider , в 32-символьная строка. И именно эта 32-символьная строка вызывала проблему, потому что она была преобразована в Base64 и передана методу PutBlock () , следовательно, в два раза длиннее и, следовательно, недопустимый хэш Служба хранения BLOB-объектов жаловалась. Вот код, с которым я столкнулся:
Оригинал:
public static string GetMD5HashFromStream(byte[] data)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
и вызов PutBlock ():
// calculate the block-level hash
string blockHash = Helpers.GetMD5HashFromStream(buff);
blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), blockHash, options);
Final:
MD5 md5 = new MD5CryptoServiceProvider();
byte[] blockHash = md5.ComputeHash(buff);
string convertedHash = Convert.ToBase64String(blockHash, 0, 16);
blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), convertedHash, options);
Роб, мне действительно любопытно, как твой код работал в твоем случае, и почему он не работал в моем - это что-то специфическое для установки на моем компьютере, или, возможно, другая версия инструментов Azure (я используя v1.2) ... Пожалуйста, дайте мне знать, если у вас есть идеи.
2) Ошибка в хранилище для разработки : большое количество прочесываний через Интернет привело меня к этой странице , где упоминается неясная, но, по-видимому, известная ошибка в хранилище для разработки:
Если два запроса пытаются загрузить
блок для блоба, который еще не
существует в хранилище разработки, один
запрос создаст BLOB-объект, а
другой может вернуть код статуса 409
(Конфликт), с услугами хранения
код ошибки BlobAlreadyExists.
Вот что я придумал, чтобы обойти это:
public static bool IsDevelopmentStorageRunning()
{
return new Microsoft.ServiceHosting.Tools.DevelopmentStorage.DevStore().IsRunning();
}
Вам нужно будет добавить ссылку на Microsoft.ServiceHosting.Tools.dll , которая находится в " C: \ Program Files \ Windows Azure SDK \ v1.2 \ bin"на моей машине. Затем я использую этот метод перед циклом Parallel.For , который обрабатывает куски файла следующим образом:
bool isDevStorageRunning = StorageProxy.IsDevelopmentStorageRunning();
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = isDevStorageRunning ? 1 : 4;
Parallel.For(0, transferDetails.Length, parallelOptions, j => { ... });
Надеюсь, это спасет кого-то от всех неприятностей, через которые я прошел. Роб, еще раз спасибо за помощь:)