Приобретите один и тот же лазурный блоб одновременно - PullRequest
0 голосов
/ 10 ноября 2018

Заметил следующее поведение в приложении моей команды:

Несколько потоков пытаются получить аренду одного и того же большого двоичного объекта, используя следующую строку:

await blob.AcquireLeaseAsync(TimeSpan.FromSeconds(lockTime), null, null, new BlobRequestOptions() { RetryPolicy = RetryPolicy }, null);

Несколько потоков успешно сданы в аренду, каждый получил разную аренду примерно в одно и то же время. Это потому, что AcquireLeaseAsync является НЕ поточно-безопасным верно? Я думал, что аренда - это блокировка, поэтому она может быть предоставлена ​​только одному потоку за раз?

Мы попытались добавить условие доступа с идентификатором аренды равным нулю, что кажется полезным.

await blob.AcquireLeaseAsync(TimeSpan.FromSeconds(lockTime), null, new AccessCondition { LeaseId = null}, new BlobRequestOptions() { RetryPolicy = RetryPolicy }, null);

Но не уверен, что это надежно, т. Е. Есть ли вероятность, что несколько потоков могут пройти это условие доступа при попытке получить в аренду этот объект?

Ниже приведен код, который я использую для создания этой проблемы:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("started");
        var storageConnStr = "";
        var client = CloudStorageAccount.Parse(storageConnStr).CreateCloudBlobClient();
        var container = client.GetContainerReference("test");
        var blob = container.GetBlobReference("Program.cs");
        List<Task> list = new List<Task>();

        for (int i = 0; i < 100; i++)
        {
            list.Add(Task.Run(() => AcquireLease(blob)));
        }
        Task.WhenAll(list).Wait();

    }
    static void AcquireLease(CloudBlob blob)
    {
        try
        {
            var id = blob.AcquireLeaseAsync(TimeSpan.FromSeconds(30), null, null, null, null).Result;
            Console.WriteLine($"Successfully acquired lease on thread {Thread.CurrentThread.ManagedThreadId}, lease id {id}, time is {DateTime.UtcNow}");
        }
        catch (Exception)
        {
            Console.WriteLine($"Got exception at {Thread.CurrentThread.ManagedThreadId}");
        }
    }
}

Пример вывода:

Успешно получен договор аренды по теме 86, идентификатор аренды dfbd393e-46e2-49dc-98f4-853356fbc255, время 10/10/2018 2:16:57

Успешно получен договор аренды на тему 22, идентификатор аренды f81b3dbf-68f6-401d-b82e-a1c19fb3527c, время 10/10/2018 2:16:57

Успешно получен договор аренды по теме 54, идентификатор аренды 6c05c2ee-c5a5-4d4e-83a9-b65688fca6df, время 11/10/2018 2:16:57

1 Ответ

0 голосов
/ 29 июля 2019

изменить var id = blob.AcquireLeaseAsync на var id = await blob.AcquireLeaseAsync

...