2

我在我的一个控制器上执行此操作,该操作由另一个方法调用,该方法也由另一个操作调用。

一切正常,除非我尝试加入 Hangfire一些工作:_bankClient.FetchAndEnsureTransactionsAsync_bankClient.RefreshItemAsync. 这导致应用程序冻结(客户端、浏览器在服务器仍在运行时停止)。我想这有点奇怪deadlock,但我尝试过的任何东西似乎都无法让它发挥作用!

有人知道如何解决这个问题吗?

我知道Hangfire还不支持调用async方法,所以我有synchronous我排队的这个方法的版本。

工作的动作

private async Task<ActionResult> ActionOnFinished(long itemId, ItemStatus status, Guid userId)
    {
        var seller = await _unitOfWork.CompanyRepository.GetCompanyByUserIdAsync(userId).ConfigureAwait(false);
        await _bankClient.CreateItemAndAccountsAsync(userId, seller.Id, itemId, seller.Name, seller.Siren.ToString()).ConfigureAwait(false);

        // TODO: use hangfire when available and fire this on BackgroundJob
        if (Properties.Settings.Default.EnableHangfire)
        {
            BackgroundJob.Schedule<IBankClientService>(bs => bs.FetchAndEnsureTransactions(userId), DateTimeOffset.Now.AddMinutes(1));
            BackgroundJob.Schedule<IBankClientService>(bs => bs.RefreshItem(userId), DateTimeOffset.Now.AddMinutes(1));
        }
        else
        {
            await _bankClient.FetchAndEnsureTransactionsAsync(userId).ConfigureAwait(false);
            await _bankClient.RefreshItemAsync(userId).ConfigureAwait(false);
        }

        return RedirectToAction(MVC.Dashboard.MyProfile());
    }

工作动作:

 private async Task<ActionResult> ActionOnFinished(long itemId, ItemStatus status, Guid userId)
    {
        var seller = await _unitOfWork.CompanyRepository.GetCompanyByUserIdAsync(userId).ConfigureAwait(false);
        await _bankClient.CreateItemAndAccountsAsync(userId, seller.Id, itemId, seller.Name, seller.Siren.ToString()).ConfigureAwait(false);

        // TODO: use hangfire when available and fire this on BackgroundJob
        await _bankClient.FetchAndEnsureTransactionsAsync(userId).ConfigureAwait(false);
        await _bankClient.RefreshItemAsync(userId).ConfigureAwait(false);

        return RedirectToAction(MVC.Dashboard.MyProfile());
    }

先例动作由私有方法调用:

private async Task<ActionResult> SelectActionByStatus(long itemId, ItemStatus status, Guid userId)
    {
        try
        {                
            if (status.Status == RefreshStatusValues.Finished)
            {
                return await ActionOnFinished(itemId, status, userId).ConfigureAwait(false);
            }

            return ActionOnError();
        }
        catch (Exception ex)
        {
            _logger.Error(ex, nameof(SelectBank));
            throw new ValidationFailureException(nameof(GetAccounts), ex.Message);
        }
    }

此操作已被另一个操作调用:

public async virtual Task<ActionResult> CallBack(string item_id)
    {
        try
        {
            var itemId = long.Parse(item_id);

            var userId = CurrentUserId.Value;
            // as this action is being called by a child window whom is being closed we need to configure the awaiter with ConfigureAwait(false)
            var status = await _bankClient.CheckItemStatusAsync(userId, itemId).ConfigureAwait(false);

            return await SelectActionByStatus(itemId, status, userId).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            _logger.Error(ex, nameof(CallBack));
            return RedirectToAction(MVC.Bank.BankError());
        }
    }

同步版本:正在排队:

public IEnumerable<Transaction> FetchAndEnsureTransactions(Guid userId)
    {
        try
        {
            return FetchAndEnsureTransactionsAsync(userId).ConfigureAwait(false).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            _logger.Error(ex, $"{nameof(FetchAndEnsureTransactions)}");
            throw;
        }
    }

public void RefreshItem(Guid userId)
    {
        try
        {
            RefreshItemAsync(userId).ConfigureAwait(false).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            _logger.Error(ex, $"{nameof(RefreshItem)}");
            throw;
        }
    }
4

0 回答 0