【问题标题】:Parallel Azure CloudBlockBlob-operations crashing (access violation)并行 Azure CloudBlockBlob 操作崩溃(访问冲突)
【发布时间】:2015-02-19 18:24:12
【问题描述】:

下面的代码示例有时会导致访问冲突(5,000 到 10,000 条消息中的 1 条)。使用串行的foreach 而不是Parallel.ForEach 似乎可以规避这个问题。

public void DequeBatch<T>(int count)
{
    var messages = this.queueListen.ReceiveBatch(count);
    var received = new ConcurrentBag<KeyValuePair<Guid, T>>();

    Action<BrokeredMessage> UnwrapMessage = message =>
        {
            blobName = message.GetBody<string>();
            obj = Download<T>(blobName);

            received.Add(new KeyValuePair<Guid, T>(new Guid(blobName), obj));
        };

    // offending operation
    Parallel.ForEach(messages, new ParallelOptions { MaxDegreeOfParallelism = count }, UnwrapMessage);
}

public override T Download<T>(string blobName)
{
    CloudBlockBlob blob;
    lock (this.containerDownloadLock)
    {
        blob = this.containerDownload.GetBlockBlobReference(blobName);
    }

    T result;
    using (var stream = new MemoryStream())
    {
        blob.DownloadToStream(stream);
        stream.Position = 0;
        result = Decompress<T>(stream);         // dehydrate an object of type T from a GZipStream
    }
    return result;
}

Q1:导致上面的代码线程不安全的违规部分是什么?

Q2:并行上传和下载CloudBlockBlobs 的正确且安全的方法是什么?

编辑

今天,上面列出的代码遇到了死锁。在调试器中点击 break-all 后,我观察到所有执行 blob.DownloadToStream(stream); 的工作线程都被困在了

System.Net.AutoWebProxyScriptEngine.EnterLock

除了一个在

中被阻止的(没有例外或其他任何东西)

System.Net.WinHttpProxyFinder.WinHttpGetProxyForUrl

【问题讨论】:

  • 异常时的调用堆栈是什么?
  • @S.T.不幸的是,大多数线程的调用堆栈根本没有显示任何代码。
  • 它显示了什么?专门针对抛出异常的线程?
  • @S.T.确切的例外是未知模块中的System.AccessViolationException。没有显示代码。

标签: c# azure azure-storage azure-blob-storage


【解决方案1】:

异常System.AccessViolationException 只能源自非托管代码或不安全的托管代码。您上面的内容是正常(即安全)托管代码,因此您目前不应仔细检查该代码,而应关注其他可能性:

  1. 您的应用程序中是否有任何非托管或不安全的代码?如果是这样,那可能是内存损坏的原因,这反过来又会导致访问冲突。 Test your app under paged heap and GFlags
  2. 在调试器下执行您的应用程序并收集故障转储。查看故障转储并检查调用堆栈中是否有熟悉的代码。 Windgb 的!analyze 命令会自动为您进行分析。您必须知道如何为您的和第 3 方库修复符号。例如here
  3. 这可能是 Microsoft 的 Blob 实现中的一个错误。

如果您合理地排除了 #1 和 #2,并且怀疑 #3 可能是问题所在,您应该收集故障转储并将其发送给 Microsoft,只有他们才能在这种情况下提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 2014-12-25
    • 1970-01-01
    • 2016-07-12
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多