【问题标题】:Create Object async异步创建对象
【发布时间】:2015-05-07 04:33:11
【问题描述】:

我有一个 XAML 应用程序,我正在做一些耗时的事情,我想异步执行这些事情以使一切变得更好。 首先,我正在创建一个连接到 Web 服务的类的实例。最好在应用程序启动后首先执行此操作并显示“正在连接到 Web 服务...”等信息
在类被实例化后,我从 WebService 获取大量数据,然后将其绑定并显示在 DataGrid 中。这是我想在显示 ProgressBar 时异步运行的第二个任务。
我了解了 async 和 await 的基础知识,但我不知道如何在应用程序窗口可见后在 async 方法中声明对象,以便我可以进一步使用它来获取数据。非常感谢任何帮助!

这是一些演示代码,显示了我的项目当前的外观。

public class ClassA
{
    public void Connect
    {
        //Connect to WebService
    }

    public List GetObjectIds
    {
        //get object IDs
    }

    public objType GetObjectById
    {
        //get complete Object
    }
}

public class MainWindow
{
    public MainWindow()
    {
        InitializeComponent()

        ClassA hello = new ClassA();
        //This takes about 15 seconds. Shall be async
        hello.Connect();

        //List will be used as Source for DataGrid
        List<object> DataGridViewSource List<object>();

        //use the instance of hello to get some Data from the WebService. 
        List<int> objectIds = new List<int>();
        objectIds = hello.GetObjectIds("LDAPQuery");

        foreach (int id in objectIds)
        {
            //this takes about 10 minutes. Shall be async
            var tmpObj = hello.GetObjectById(id);
            DataGridViewSource.Add(tmpObj);
        }

        //do binding to DataGrid
    }
}

【问题讨论】:

  • 我是否正确理解 for 循环应该异步运行?
  • 请比更具体“但我没有任何运气来实现这个”。请务必提供a good, minimal, complete code example,该a good, minimal, complete code example 可靠且清楚地说明了您迄今为止所做的尝试以及该尝试的作用,并清楚、详细地解释了为什么以及如何与您希望代码执行的操作不同。
  • 你是对的。我已经编辑了我的问题。我的主要问题是在应用程序窗口可见后如何以及在何处异步声明对象。
  • 请注意,WPF 具有异步绑定(与 C# 的 async/await 不同),这可能更合适,因为您经常希望对属性进行异步评估,而属性不能使用 await。否则,我建议将异步代码放入可以是异步的事件处理程序中,例如 Loaded 事件而不是构造函数。

标签: c# wpf asynchronous


【解决方案1】:

您不能在构造函数中使用await 异步代码,但可以在事件中使用。 Loaded,例如:

public MainWindow()
{
    // At design time (in your XAML), initialize to the "Loading..." state
    InitializeComponent()
}

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    ClassA hello = new ClassA();
    await hello.ConnectAsync();

    //List will be used as Source for DataGrid
    List<object> DataGridViewSource List<object>();

    //use the instance of hello to get some Data from the WebService. 
    List<int> objectIds = new List<int>();
    objectIds = hello.GetObjectIds("LDAPQuery");

    foreach (int id in objectIds)
    {
        var tmpObj = await hello.GetObjectByIdAsync(id);
        DataGridViewSource.Add(tmpObj);
    }

    //do binding to DataGrid
}

【讨论】:

  • 好吧,该事件处理程序中的异步操作是一个触发后忘记操作,如果您想通过调用而不是等待或awaiting,一个@@ 987654325@方法。
  • @Servy:如果您接受静默异常吞咽,是的。 :)
  • 如果您愿意,可以显式处理异常,或者如果您确实想要相同的错误处理语义,则只需从构造函数中调用async void 方法。
猜你喜欢
  • 2020-10-16
  • 2018-03-16
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-10
相关资源
最近更新 更多