2

ストリームを使用して、Azure ローカル開発アカウントに直接アップロードしたいと考えています。Azure BLOB ストレージのクラスを作成しました。

public class AzureBlob
{
    delegate void UploadFinished(IAsyncResult result);
    public void uploadFile()
    {
        //Initial configuration
        CloudStorage account = CloudStorageAccount.DevelopmentStorageAccount;
        CloudBlobClient client = account.CreateBlobClient();
        CloudBlobContainer container = client.GetContainerReference("myfiles");
        Stream stream = new MemoryStream();

        //Upload to azure
        CloudBlob blob = container.GetBlobReference("sample.txt");
        UploadFinished uploadFinished = delegate(IAsyncResult result)
        {
            Console.WriteLine("Upload finished {0} {1}", result.IsCompleted, stream.Position);
        };
        blob.BeginUploadFromStream(stream, new AsyncCallback(uploadFinished));

        //Write to stream
        for(int i=0;i<100;i++)
        {
            for(int j=0;j<50;j++)
            {
                stream.WriteByte(65);
            }
        }
        stream.Close();


    }
}

私が直面する最初の問題は、ストレージにファイルを取得することですが、データが含まれていません。コールバックで EndOfUploadStream メソッドを使用しても (スタックオーバーフローの回答によると、これは解決策です)。次に、コールバック内にブレークポイントを配置すると、ストリームを閉じる前にコールバックが 1 回実行され、プログラムがストリームを更新し続けることがわかりました。この時点で、ストリームの位置は 913 付近 (ほぼランダム) です。非同期でストリームを介してブロブを直接アップロードするのを手伝ってください。

4

2 に答える 2

2

great answer from smarx! Also, move stream.Close() into the callback.

delegate void BeginUploadFinished(IAsyncResult result);
public void UploadFile()
{
    //Initial configuration
    var account = CloudStorageAccount.DevelopmentStorageAccount;
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference("myfiles");
    Stream stream = new MemoryStream();
    var state = new Object{};

    //Upload to azure
    var blob = container.GetBlobReference("test.txt");
    BeginUploadFinished beginUploadFinished = delegate(IAsyncResult result)
    {
        blob.EndUploadFromStream(result);
        Trace.WriteLine("EndUploadFromStream", "Information");
        stream.Close();
        stream.Dispose();
    };

    //Write to stream
    Trace.WriteLine("Writing Stream", "Information");
    for (var i = 0; i < 100; i++)
    {
        for (var j = 0; j < 50; j++)
        {
            stream.WriteByte(65);
        }
    }
    stream.Seek(0, SeekOrigin.Begin);

    Trace.WriteLine("BeginUploadFromStream", "Information");
    var _result =  blob.BeginUploadFromStream(stream, new AsyncCallback(beginUploadFinished), state);
    _result.AsyncWaitHandle.WaitOne();
}
于 2012-12-15T18:54:34.180 に答える
2

競合状態にあるように見えます。実際にコンテンツをストリームに入れる前に、ストリームのアップロードを開始します。

おそらく次のようなものが必要です。

Stream stream = new MemoryStream();

//Write to stream
for(int i=0;i<100;i++)
{
    for(int j=0;j<50;j++)
    {
        stream.WriteByte(65);
    }
}
stream.SetPosition(0); // <-- need to reset stream position to 0 before uploading

//Upload to azure
CloudBlob blob = container.GetBlobReference("sample.txt");
UploadFinished uploadFinished = delegate(IAsyncResult result)
{
    blob.EndUploadFromStream(result); // <-- have to call this in your handler
    Console.WriteLine("Upload finished {0} {1}", result.IsCompleted, stream.Position);
};
blob.BeginUploadFromStream(stream, new AsyncCallback(uploadFinished));
于 2012-12-15T16:57:40.190 に答える