У меня возникают трудности с поиском правильного способа вызова dispose для потока после вызова метода асинхронной загрузки.
Ниже вы увидите метод, который я использую для загрузки файла в Azure асинхронным способом, и я создал AsyncCallback, потому что мне нужно записывать в журнал все успешные и неудачные операции.
Я написал метод в асинхронном режиме, пытаясь добиться чуть большей производительности (это API, который получает json с десятками - возможно, сотнями изображений URL-адресов для загрузки в Azure).
Метод работает просто отлично, но я не уверен, как / где располагать объект потока, выделенный жирным шрифтом. Я прокомментировал использование, потому что, используя его, я получаю неожиданные результаты, предположительно из-за того, что поток был удален до загрузки, я думаю.
В качестве дополнительной информации, у основного метода, который вызывает upload, есть три вложенных foreach, который перебирает json, и TmpModelsJsonIterationInfo - это класс, который содержит текущий элемент, повторяемый для трех foreach, потому что я нужны они в основном для бревна.
В методе main я создаю основной (оригинальный) поток по URL-адресу, указанному в json, и передаю его в метод загрузки (как свойство TmpModelsJsonIterationInfo), где размер изображения изменяется в соответствии с массивом размеров (разрешений), поэтому для каждого размера создается новый поток, и это поток, я не уверен, где его закрыть / удалить.
Может быть, я могу добавить новое свойство к TmpModelsJsonIterationInfo для удержания потока и размещения его в OnUploadCompleted так же, как я делаю с исходным потоком?
private void UploadFile(TmpModelsJsonIterationInfo tmpModelsJsonIterationInfo)
{
try
{
foreach (KeyValuePair<string, (int Width, int Height)> size in VersionDefinitions.AssetResolutions)
{
Stream **stream** = resizeImage(tmpModelsJsonIterationInfo.CurrentOriginalStreamFile, size);
stream.Position = 0;
//using (Stream stream = resizeImage(tmpModelsJsonIterationInfo.CurrentOriginalStreamFile, size)) {
//stream.Position = 0;
string sizeName = size.Key;
string azureFile = sizeName + "/" + tmpModelsJsonIterationInfo.CurrentAssetId;
CloudBlockBlob blockBlob = Azure.GetBlockBlobReference(_container, azureFile);
blockBlob.Properties.ContentType = tmpModelsJsonIterationInfo.CurrentContentType;
tmpModelsJsonIterationInfo.CurrentBlockBlob = blockBlob;
tmpModelsJsonIterationInfo.CurrentSize = sizeName;
AsyncCallback UploadCompleted = new AsyncCallback(OnUploadCompleted);
blockBlob.BeginUploadFromStream(stream, UploadCompleted, tmpModelsJsonIterationInfo);
//}
}
}
catch (Exception e)
{
logMessage("KO - Uploading assetId: " + tmpModelsJsonIterationInfo.CurrentAssetId + ": " + e.Message, Level.Error);
}
}
private void OnUploadCompleted(IAsyncResult result)
{
TmpModelsJsonIterationInfo tmpModelsJsonIterationInfo = (TmpModelsJsonIterationInfo)result.AsyncState;
tmpModelsJsonIterationInfo.UploadCounter++;
try
{
CloudBlockBlob blockBlob = tmpModelsJsonIterationInfo.CurrentBlockBlob;
blockBlob.SetMetadata();
blockBlob.EndUploadFromStream(result);
//log OK
if (blockBlob.Properties.Length != -1)
{
tmpModelsJsonIterationInfo.CurrentOrderedAsset["AssetId"] = tmpModelsJsonIterationInfo.CurrentAssetId;
tmpModelsJsonIterationInfo.CurrentOrderedAsset["State"] = true;
string newLine = Environment.NewLine;
logMessage(
"Upload OK" + newLine +
"ModelVencaID: " + tmpModelsJsonIterationInfo.CurrentModelId + newLine +
"ColorVencaID: " + tmpModelsJsonIterationInfo.CurrentColorId + newLine +
"AssetId: " + tmpModelsJsonIterationInfo.CurrentAssetId + newLine +
"Source Url: " + tmpModelsJsonIterationInfo.CurrentUrl + newLine +
"Target Url: " + DataBridgeSettings.Instance.AzureImagesDomainURL +
"/images/" + tmpModelsJsonIterationInfo.CurrentSize + "/" + tmpModelsJsonIterationInfo.CurrentAssetId + newLine +
"---------", Level.Info);
} else {
tmpModelsJsonIterationInfo.CurrentOrderedAsset["AssetId"] = 0;
tmpModelsJsonIterationInfo.CurrentOrderedAsset["State"] = false;
}
if (tmpModelsJsonIterationInfo.UploadCounter == _numberOfSizes) {
tmpModelsJsonIterationInfo.CurrentOriginalStreamFile.Close();
tmpModelsJsonIterationInfo.CurrentOriginalStreamFile.Dispose();
}
}
catch (Exception e)
{
tmpModelsJsonIterationInfo.CurrentOrderedAsset["AssetId"] = 0;
tmpModelsJsonIterationInfo.CurrentOrderedAsset["State"] = false;
logMessage("KO - Uploading assetId: " + tmpModelsJsonIterationInfo.CurrentAssetId + ": " + e.Message, Level.Error);
}
}