1

次の投稿に従って、チャンクでブロブにアップロードしました

Azure ストレージへの非同期ファイル アップロードの進行状況を追跡する方法

ただし、win 8.1 アプリでは MemoryStream がサポートされていないため、これは Windows ストア アプリまたは Windows 8.1 アプリでは機能しません。

とにかく、上記のスレッドのコードを変更し、次のようなものを考え出しました

        CloudBlobClient myBlobClient = storageAccount.CreateCloudBlobClient();
        var filePicker = new FileOpenPicker();

        filePicker.FileTypeFilter.Add("*");
        var file = await filePicker.PickSingleFileAsync();
        string output = string.Empty;

            var fileName = file.Name;


        myBlobClient.SingleBlobUploadThresholdInBytes = 1024 * 1024;
        CloudBlobContainer container = myBlobClient.GetContainerReference("files");
        //container.CreateIfNotExists();
        CloudBlockBlob myBlob = container.GetBlockBlobReference(fileName);
        var blockSize = 256 * 1024;
        myBlob.StreamWriteSizeInBytes = blockSize;

        var fileProp = await file.GetBasicPropertiesAsync();
        var bytesToUpload = fileProp.Size;
        var fileSize = bytesToUpload;



        if (bytesToUpload < Convert.ToUInt64(blockSize))
        {
            CancellationToken ca = new CancellationToken();
            var ado = myBlob.UploadFromFileAsync(file).AsTask();
            await
                            //Console.WriteLine(ado.Status); //Does Not Help Much
                            ado.ContinueWith(t =>
                            {
                                //Console.WriteLine("Status = " + t.Status);
                                //Console.WriteLine("It is over"); //this is working OK
                            });
        }
        else
        {
            List<string> blockIds = new List<string>();
            int index = 1;
            ulong startPosition = 0;
            ulong bytesUploaded = 0;
            do
            {
                var bytesToRead = Math.Min(Convert.ToUInt64(blockSize), bytesToUpload);
                var blobContents = new byte[bytesToRead];




                using (Stream fs = await file.OpenStreamForWriteAsync())
                {
                    fs.Position = Convert.ToInt64(startPosition);
                    fs.Read(blobContents, 0, (int)bytesToRead);
                    //var iStream = fs.AsInputStream();



                    ManualResetEvent mre = new ManualResetEvent(false);
                    var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(index.ToString("d6")));
                    //Console.WriteLine("Now uploading block # " + index.ToString("d6"));
                    blockIds.Add(blockId);
                    var ado = myBlob.PutBlockAsync(blockId, fs.AsRandomAccessStream(), null).AsTask();
                    await ado.ContinueWith(t =>
                              {
                                  bytesUploaded += bytesToRead;
                                  bytesToUpload -= bytesToRead;
                                  startPosition += bytesToRead;
                                  index++;
                                  double percentComplete = (double)bytesUploaded / (double)fileSize;
                                  output += (percentComplete * 100).ToString() + ",";
                        // AppModel.TasksFormObj.SetProgress(percentComplete * 100);
                        // Console.WriteLine("Percent complete = " + percentComplete.ToString("P"));
                        mre.Set();
                              });

                mre.WaitOne();
                }
            }
            while (bytesToUpload > 0);
            //Console.WriteLine("Now committing block list");
            var pbl = myBlob.PutBlockListAsync(blockIds).AsTask();
             pbl.ContinueWith(t =>
            {
                //Console.WriteLine("Blob uploaded completely.");
            });
        }
    }

上記のコードはファイルを blob に保存し、進行状況も問題ありませんが、blob に保存されたファイルは常に 0 バイトです。デバッグ後、 var ado = myBlob.PutBlockAsync(blockId, fs.AsRandomAccessStream(), null).AsTask(); の後にエラーがスローされることがわかりました。最後のブロブ転送の場合

<?xml version="1.0" encoding="utf-16"?>
<!--An exception has occurred. For more information please deserialize this message via RequestResult.TranslateFromExceptionMessage.-->
<RequestResult>
  <HTTPStatusCode>400</HTTPStatusCode>
  <HttpStatusMessage>The value for one of the HTTP headers is not in the correct format.</HttpStatusMessage>
  <TargetLocation>Primary</TargetLocation>
  <ServiceRequestID>13633308-0001-0031-060b-7249ea000000</ServiceRequestID>
  <ContentMd5 />
  <Etag />
  <RequestDate>Sun, 28 Feb 2016 10:31:44 GMT</RequestDate>
  <StartTime>Sun, 28 Feb 2016 09:31:43 GMT</StartTime>
  <EndTime>Sun, 28 Feb 2016 09:31:44 GMT</EndTime>
  <Error>
    <Code>InvalidHeaderValue</Code>
    <Message>The value for one of the HTTP headers is not in the correct format.
RequestId:13633308-0001-0031-060b-7249ea000000
Time:2016-02-28T09:34:18.3545085Z</Message>
    <HeaderName>Content-Length</HeaderName>
    <HeaderValue>0</HeaderValue>
  </Error>
  <ExceptionInfo>
    <Type>StorageException</Type>
    <HResult>-2147467259</HResult>
    <Message>The value for one of the HTTP headers is not in the correct format.</Message>
    <Source>Microsoft.WindowsAzure.Storage</Source>
    <StackTrace>   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.&lt;ExecuteAsyncInternal&gt;d__c`1.MoveNext()</StackTrace>
  </ExceptionInfo>
</RequestResult>

次に、最後のコミットで、 myBlob.PutBlockListAsync(blockIds) の後にエラーがスローされます 指定されたブロックリストが無効です

だから、誰かが私がどこで間違っているのか、またはそれを100%機能させるための可能な解決策は何かを理解するのを手伝ってください.

4

1 に答える 1

0

このように使用AsTask()します。

 CancellationTokenSource _cts;

 _cts = new CancellationTokenSource();//<--In Constructor 

 var progress = new Progress<double>(TranscodeProgress); 
 await var ado = myBlob.UploadFromFileAsync(file).AsTask(_cts.Token, progress); 
于 2016-03-01T08:03:17.937 に答える