2014-06-15 5 views
6

Ho un servizio molto semplice,parallelo Blob Carica gettando 404 Bad Request intermittenza

public class AzureService : IAzureService 
{ 
    private readonly CloudBlobContainer _container; 
    public AzureService(ISettings settings) 
    { 
     var storageAccount = CloudStorageAccount.Parse(settings.BlobConnectionString);    
     var blobClient = storageAccount.CreateCloudBlobClient(); 
     _container = blobClient.GetContainerReference(settings.BlobContainerName); 
    } 

    public Task UploadBlobAsync(string fileName, Stream stream) 
    { 
     var blob = _container.GetBlockBlobReference(fileName); 
     return blob.UploadFromStreamAsync(stream); 
    } 

    public Task DeleteBlobAsync(string fileName) 
    { 
     var blob = _container.GetBlockBlobReference(fileName); 
     return blob.DeleteAsync(); 
    } 
} 

Questo metodo viene chiamato da,

public Task SaveAllAsync(Dictionary<string, Stream> images) 
    { 
     var tasks = new List<Task>(); 
     foreach (var image in images) 
     { 
      var fileName = image.Key; 
      var stream = image.Value; 
      var task = _azureService.UploadBlobAsync(fileName, stream); 
      tasks.Add(task); 
     } 
     return Task.WhenAll(tasks); 
    } 

mio stream è HttpPostedFileBase.InputStream. A volte funziona e talvolta ottengo The remote server returned an error: (400) Bad Request.. Se metto un break-point funziona pure.

+0

400 è sicuramente un errore del server dicendo che il cliente ha inviato una richiesta non valida. Prova a usare Fiddler per vedere cosa c'è di diverso tra le richieste buone e quelle cattive. –

+0

@PauloMorgado, Se attendo UploadFromStreamAsync' allora funzionerà – user960567

+0

In attesa di 'UploadFromStreamAsync' non dovrebbe avere alcun effetto. Hai controllato il contenuto HTTP con Fiddler? –

risposta

1

Ho avuto lo stesso problema, ho provato a caricare 20 + immagini in 1 sciopero, opere a thread singolo, multi-threaded con await Task.WhenAll non riuscita con "Il server remoto ha restituito un errore: (400) Bad Request. "

  • vedere RequestInformation all'interno Microsoft.WindowsAzure.Storage.StorageException che viene gettato dalla Carica [xxx] metodi asincroni per informazioni più dettagliate.

  • In un primo momento, RequestInformation detto qualcosa a proposito di un problema MD5 con il codice di errore di "Md5Mismatch", comprare la mia intuizione ha detto altrimenti, perché solo filo funziona come un fascino, e poi .. ho trovato ... DefaultRequestOptions.ParallelOperationThreadCount su CloudBlobClient oggetto e problema sovled.

  • BlobRequestOptions Members MSDN


private CloudBlobContainer ConnectToImageContainer() 
    { 
     var credentials = new StorageCredentials(AccountName, ImagesContainerKey); 
     var account = new CloudStorageAccount(credentials, useHttps: true); 
     var client = account.CreateCloudBlobClient(); 
     client.DefaultRequestOptions.ParallelOperationThreadCount = 64; // max value 
     client.DefaultRequestOptions.SingleBlobUploadThresholdInBytes = 67108864; // max value 
     var container = client.GetContainerReference(ImagesContainerName); 
     return container; 
    } 
0

Il comportamento che si sta descrivendo suona molto simile a un problema di threading (ad esempio se si interrompe il codice funziona correttamente poiché è effettivamente single-threading in quel momento) causando dati incompleti o non validi inviati all'API di archiviazione di Azure.

La definizione di "var image" può comportarsi inaspettatamente in un ambiente a più thread (se si utilizza ReSharper, questa variabile verrà evidenziata e si consiglia di modificare il codice perché potenzialmente non sicuro).

Leggi questo post in SO per capire un po 'di più e come potresti implementare meglio il tuo codice.

The foreach identifier and closures