c # Azure MVC проверка, существует ли blob от контроллера - PullRequest
0 голосов
/ 19 марта 2019

Мне нужно проверить наличие большого двоичного объекта в действии контроллера MVC, и я пытаюсь сделать это асинхронным способом безуспешно.

Если я делаю проверку синхронно, она работает нормально иЯ получаю желаемый результат, и код выглядит следующим образом:

public ActionResult Index(string id, string size)
{
    string redirectUrl;
    if (string.IsNullOrEmpty(assetBlobUrl)) assetBlobUrl = ConfigurationManager.AppSettings["AssetBlobUrl"];
    if (!string.IsNullOrEmpty(assetBlobUrl))
    {
        bool blobExists = _blobExists(size, id);
        if (blobExists)
        {
            redirectUrl = string.Format(assetBlobUrl, size, id);
            return new PermanentRedirectResult(redirectUrl);
        }
    }

    return ResponseImageNotFound();
}

private bool _blobExists(string size, string assetId)
{
    var container = serviceClient.GetContainerReference("images");
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(size + "/" + assetId + ".jpg");
    bool checkBlobExists = blockBlob.Exists();

    return checkBlobExists;
}

Асинхронная (не работающая) версия выглядит следующим образом:

public ActionResult Index(string id, string size)
{
    string redirectUrl;
    if (string.IsNullOrEmpty(assetBlobUrl)) assetBlobUrl = ConfigurationManager.AppSettings["AssetBlobUrl"];
    if (!string.IsNullOrEmpty(assetBlobUrl))
    {
        bool blobExists = _blobExists(size, id).Result;
        if (blobExists)
        {
            redirectUrl = string.Format(assetBlobUrl, size, id);
            return new PermanentRedirectResult(redirectUrl);
        }
    }

    return ResponseImageNotFound();
}

private async Task<bool> _blobExists(string size, string assetId)
{
    bool blobExists = await container.GetBlockBlobReference(size + "/" + assetId + ".jpg").ExistsAsync();

    return blobExists;
}

Но этот последний способ загрузки веб-страниц продолжаетсяи строка с ExistsAsync никогда не заканчивается, поэтому следующее возвращение никогда не выполняется.

Любая помощь?

Спасибо.

1 Ответ

1 голос
/ 19 марта 2019

Проблема заключается в вызове .Result, что, как правило, является плохой практикой, поскольку ее можно избежать.

Когда метод _blobExists выполняет await, он уходит, выполняет задание, затем пытается вернуться и возобновить работу. Проблема в том, что ваш предыдущий вызов .Result заблокировал поток, потому что он ждет, пока _blobExists завершит получение Result. Итак, _blobExists ждет, пока поток освободится, чтобы он мог продолжить выполнение метода и вернуть ваш результат.

Это означает, что в итоге вы получите тупиковый сценарий, оба ждут друг друга.

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

public async Task<ActionResult> Index(string id, string size) должен исправить это.

Однако вам все же нужно быть осторожным, если вы не используете .NET Core, вам следует указать, что вам не нужен тот же контекст синхронизации, в противном случае проблема все еще может возникнуть, поместив .ConfigureAwait(false) на * 1020. * строка.

...