c# - 如何在数据库值之后等待然后继续

标签 c# asp.net-mvc multithreading paypal

我有一个使用 PayPal 自适应支付的电子商务网站。自适应支付请求 PayPal 生成 PayKey 以创建发票。获取 PayKey 的延迟足够长,因此我想到将代码放在单独的线程中,而用户在重定向到 PayPal 之前回答一些其他问题,请参阅下面的代码:

    await Task.Run<Task>(async () =>
    {
        var payResponse = await _payPalApplicationService.ProceedWithPayPal(currentEvent.Id, order.InvoiceId, order.TrackingId, owners.Single(), vModel.TotalPrice, vModel.DeliveryPriceTotal, orderToAdd.TotalTaxes, orderToAdd.SalesRate + orderToAdd.SalesRateTaxes, vModel.SKUViewModels, _payPalApplicationService.PayPalCore._serviceEndPointUrl);
        order.PayKey = payResponse.payKey;

        _orderService.Update(order);
        await _unitOfWorkAsync.SaveChangesAsync();
    });

我遇到的问题是,有些用户的速度足够快,因此在重定向到 PayPal 之前尚未生成 PayKey。

您知道我可以做些什么来确保在将用户重定向到 PayPal 之前获得 PayKey 吗?线程任务是在与重定向不同的 Controller 操作中完成的。

谢谢

大卫

最佳答案

这可能违反了 MVC 无状态原则,但一个非常简单的解决方案是针对 session 存储 PayKey 检索任务。

所以将上面的代码修改为:

Session["PaypalTask"] = await Task.Run<Task>(async () =>
{
    var payResponse = await _payPalApplicationService.ProceedWithPayPal(currentEvent.Id, order.InvoiceId, order.TrackingId, owners.Single(), vModel.TotalPrice, vModel.DeliveryPriceTotal, orderToAdd.TotalTaxes, orderToAdd.SalesRate + orderToAdd.SalesRateTaxes, vModel.SKUViewModels, _payPalApplicationService.PayPalCore._serviceEndPointUrl);
    order.PayKey = payResponse.payKey;

    _orderService.Update(order);
    await _unitOfWorkAsync.SaveChangesAsync();
});

然后您可以稍后在其他 Controller 中检索该任务并在那里等待。如果已经完成执行将立即继续,否则将等待执行完成后再继续。

类似这样的事情

public async Task<ActionResult> Index()
{
    var payPalTask = Session["PaypalTask"] as Task;

    await payPalTask;

    return RedirectToAction("CompltedPayment");
}

当然,您可能还需要考虑错误处理等。

更新

我应该提到,上述方法将 session 状态存储在内存中。如果您的应用程序使用多个服务器,您可能想要研究粘性 session 或某种分布式缓存(如 redis),则会出现一些复杂情况。

更新2:

我已经发布了一个演示,使用简单的 Task.Delay 来模拟异步方法 here 。如果您构建此 Web 应用程序,然后导航到/InitiatePp,它将启动请求。然后/PpResult/Result 将给出正在运行的任务的状态,而/PpResult/Wait 将等待任务完成。

关于c# - 如何在数据库值之后等待然后继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45091275/

相关文章:

c++ - 基于C++11的线程类库

java - 如何在另一个线程JAVA中访问 volatile 变量

c# - 编写 Unity 后处理堆栈脚本

jquery - ASP.NET MVC 中的链接样式失败问题

javascript - 如何从 MVC4 中的 Javascript 检查 View 模型中的模型值

c# - 在一个 Controller 中有很多方法 VS 在多个 Controller 中有很多方法

c# - 在另一个线程上访问数据

c# - 拆分字符串并转换为自定义类型

c# - 是否可以在 Rational Rose 中对 C# 代码进行逆向工程?

c# - 不可变变量和不可变对象(immutable对象)