我在我的一个控制器上执行此操作,该操作由另一个方法调用,该方法也由另一个操作调用。
一切正常,除非我尝试加入 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;
}
}