【问题标题】:C# - How update a web page after an async method call?C# - 如何在异步方法调用后更新网页?
【发布时间】:2016-01-24 10:28:53
【问题描述】:

我有一个网页,其中包含添加设备的表单。

当用户添加设备时,设备会在 4 个不同的地方注册。 由于这 4 个注册中的每一个都需要时间,因此我决定使用异步调用。

因此,当用户单击保存按钮时,会向服务器触发 AJAx 请求并调用“保存”方法。 “Save”方法有一个循环,异步调用“Register”方法,如下所示:

public delegate bool DeviceControllerAsync(...);

public static string Save(...)
{
    //Get all active controllers
    List<Controller> lstControllers = Controller.Get();
    foreach (Controller controller in lstControllers)
    {
        // Invoke asynchronous write method
        DeviceControllerAsync caller = new DeviceControllerAsync(ArubaBL.RegisterDevice);

        // Initiate the asychronous call.
        IAsyncResult result = caller.BeginInvoke(..., null, null);
    }
    return GetRegisteredDevices();
}

这里的问题是“GetRegisteredDevices”调用是没有意义的,因为异步方法还没有完成,并且没有设备可以返回。 此外,当这些操作完成后,我无法更新 UI,因为 main 方法已经返回到 UI。

(如果用户在单击“保存”按钮后立即移动另一个页面,我将忽略此情况。)

那么,有没有办法让我知道所有异步调用何时完成,然后调用将更新 UI 的方法?

【问题讨论】:

  • 你能迁移到 TPL 来代替旧式的 begin/endinvoke 吗?
  • this 可能有帮助
  • 如果我知道 TPL 是什么,我可以迁移到 TPL...什么是 TPL ???
  • 我认为async/await 会比基本的 TPL 更容易...请更新您帖子上的标签以指定您使用的框架(除了普通的 ASP.Net 之外的任何东西都可以轻松使用 async/await)

标签: c# asynchronous web .net-4.0 entity-framework-4


【解决方案1】:

使用 TPL 库和 async/await 关键字的简化示例。

public static async string Save(...)
{
    //Get all active controllers
    List<Controller> lstControllers = Controller.Get();

    //Create a task object for each async task
    List<Task<returnValueType>> controllerTasks = lstControllers.Select(controller=>{
        DeviceControllerAsync caller = new DeviceControllerAsync(ArubaBL.RegisterDevice);
        return Task.Factory.FromAsync<returnValueType>(caller.BeginInvoke, caller.EndInvoke, null);
    }).ToList();

    // wait for tasks to complete (asynchronously using await)
    await Task.WhenAll(controllerTasks);

    //Do something with the result value from the tasks within controllerTasks
}

【讨论】:

  • 知道为什么这段代码不能编译吗? 'System.Threading.Tasks.Task' does not contain a definition for 'WhenAll'
  • @Liran 是的,Task.WhenAll 在 .NET 4 上不可用。试试 NuGet 的 Microsoft.Bcl.Async 包。
  • 我正在使用 Visual Studio 2010。不幸的是:“Visual Studio 2010 不支持此程序包,只有面向 .NET Framework 4.5、Windows 8、Windows Phone Silverlight 8 或使用使用此包的库时的 Windows Phone 8.1。"
  • 我可以改用Task.Factory.ContinueWhenAll 吗?
  • @Liran ContinueWhenAll 不会同步等待。您可以使用Task.WaitAll,它正是这样做的。请注意,它会阻塞调用线程,直到所有任务完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 2012-08-08
  • 2017-03-06
相关资源
最近更新 更多