如何应用异步并等待List <T>?

时间:2019-08-12 07:30:49

标签: c# asp.net multithreading async-await

我想异步显示项目列表,我的工作方式如下,但我不确定它是否正常工作。你们可以帮我吗,这是正确的方法吗?

private List<SuggestedItemsInput> SuggestedItemAsync()
{
   OHDWebService OHDService = new OHDWebService();
   List<SuggestedItemsInput> suggestedItemsList = OHDService.SaveSuggestedItems(hdnPlainBody.Value, hfdOrderRecordID.Value);
   return suggestedItemsList;
}

private async void GetSuggestedItemsFromService()
{
   Task<List<SuggestedItemsInput>> task = new Task<List<SuggestedItemsInput>>(SuggestedItemAsync);
   task.Start();
   List<SuggestedItemsInput> suggestedItems = await task;
   ViewState["sItems"] = suggestedItems;
   if (suggestedItems != null && suggestedItems.Count > 0)
   {
       GetSuggestedItems(Request["OrderRecordID"].ToString());
       lblInfo.Text = string.Empty;
   }
}

编辑: 现在,我正在使用下面的代码,它正在运行,并且通过SaveAndGetSuggestedItem()方法保存和获取数据。将数据保存在数据库中需要花费时间,同时我想在完成后显示加载图像,加载图像应隐藏并且数据应在grid-view中填充,我在下面添加了代码,但是问题是grid-view将在手动刷新页面并加载连续显示的图片后加载。

    /// <summary>
    /// Gets the SuggestedItems from API.
    /// </summary>
    private List<SuggestedItemsInput> SaveAndGetSuggestedItem()
    {
        try
        {
            OHDWebService OHDService = new OHDWebService();
            return OHDService.SaveSuggestedItems(hdnPlainBody.Value, hfdOrderRecordID.Value);
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    /// <summary>
    /// Async call to the SuggestedItems.
    /// </summary>
    private async Task GetSuggestedItemsAsync()
    {
        try
        {

            LoadingImg.Visible = true;
            List<SuggestedItemsInput> suggestedItems = await Task.Run(() => SaveAndGetSuggestedItemFromKenome());
            LoadingImg.Visible = false;

            ViewState["sItems"] = suggestedItems;
            if (suggestedItems != null && suggestedItems.Count > 0)
            {
                BindSuggestedItems(hfdOrderRecordID.Value);
                lblInfo.Text = string.Empty;
            }
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

首页(查看):

 <asp:Panel ID="LoadingImg" runat="server" Visible="false">
                            <i class="fa fa-spinner fa-pulse fa-3x fa-fw" style="color: darkblue"></i>
                            <span class="sr-only">Loading...</span><span>Please wait...</span>
                        </asp:Panel>
                        <asp:Label ID="lblInfo" runat="server"></asp:Label>
                        <asp:GridView ID="grdSuggestedItems" runat="server" CellPadding="4" CellSpacing="4" AutoGenerateColumns="false" Width="100%" CssClass="table" HorizontalAlign="Center">
                            <HeaderStyle HorizontalAlign="Center" BackColor="#8b6f4e" ForeColor="white" />
                            <Columns>
                                <asp:BoundField HeaderText="Matched Text" DataField="MessageText" />
                                <asp:TemplateField HeaderText="ItemId">
                                    <ItemTemplate>
                                        <div>
                                            <span style="font-size: 12px;">
                                                <a target="_blank" style="cursor: pointer" href='<%= ConfigurationManager.AppSettings["InvInquiry"].ToString() %><%#Eval("ItemID") %>'><%#Eval("ItemID") %></a>
                                            </span>
                                            <div style="font-size: 10px;">
                                                <%#Eval("ItemDescription") %>
                                            </div>
                                        </div>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:BoundField HeaderText="ProductLine" DataField="ProductLine" />
                                <asp:BoundField HeaderText="Qty" DataField="Qty" />
                                <asp:BoundField HeaderText="Confidence(%)" DataField="Confidence" />
                                <asp:BoundField HeaderText="Rank" DataField="Rank" />
                            </Columns>
                            <RowStyle HorizontalAlign="Center" />
                        </asp:GridView>

1 个答案:

答案 0 :(得分:3)

好几件事。

  • 您的SuggestedItemAsync方法不是异步的,它返回多个项目,因此应称为SuggestedItems。由于最好了解与“ SuggestedItems”有关的什么,因此,我也考虑像在其他方法上一样在前面添加Get。所以GetSuggestedItems是我要选择的名称。
  • 除非您将方法用作事件处理程序(向后兼容),否则请不要使用async void。如果没有返回类型,请改用async Task
  • 您的GetSuggestedItemsFromService方法是异步的,因此应将其命名为GetSuggestedItemsFromServiceAsync
  • 我不知道OHDWebService是什么,但是您应该检查它是否实现了IDisposable,如果是,请将其包装在using-statement中。

我假设您只想异步启动方法SuggestedItems,因为它需要很长时间。您可以使用Task.Run进行此操作,这比显式创建新任务要好得多。

这是我重写您的代码的方式:

private List<SuggestedItemsInput> GetSuggestedItems()
{
    OHDWebService OHDService = new OHDWebService();
    return OHDService.SaveSuggestedItems(hdnPlainBody.Value, hfdOrderRecordID.Value);
}

private async Task GetSuggestedItemsFromServiceAsync()
{
    List<SuggestedItemsInput> suggestedItems = await Task.Run(() => GetSuggestedItems());

    ViewState["sItems"] = suggestedItems;
    if (suggestedItems != null && suggestedItems.Count > 0)
    {
        GetSuggestedItems(Request["OrderRecordID"].ToString());
        lblInfo.Text = string.Empty;
    }
}

编辑:
因此,在经过一些评论之后,还有更多事情要提及。

  • GetSuggestedItems方法似乎还保存了一些值,因此也许SaveSuggestedItemsSaveAndGetSuggestedItems是更合适的名称。
  • GetSuggestedItems方法使用未定义的hdnPlainBody(或者您未在其中显示代码)。您是要将此参数设为参数吗?如果是这样,它必须是某个具有Value属性的类/结构。但是在GetSuggestedItemsFromServiceAsync方法中,您以GetSuggestedItems作为参数调用string方法。是否有接受string且您没有向我们显示的超载?

最后是实际问题。我将在此处添加您的评论,这很清楚我们在谈论什么:

  

SuggestedItemAsync将保存数据并返回列表,但是当光标进入等待状态时,它将不允许运行下一行,但数据将保存在db中。

我从中得到的是,您希望数据的插入和获取异步地逐行进行。
为了实现这一点,OHDService.SaveSuggestedItems的实现必须是async并支持该实现。在您的代码中,它不是async,因此,实现逐行行为的唯一方法是迭代输入的数据,并异步进行,一次插入一行。您没有提供足够的背景信息,很遗憾,我无法为您提供帮助。
另外,由于您提到它已经(太)长时间了,所以将其包装为异步可能不是一个好主意,因为它将花费更长的时间。

我认为您应该提供更多信息。我们真的不能为您提供帮助,因为:

  • 您使用string作为参数调用无参数方法,但没有提及任何内容
  • 您没有指定期望的行为(请参阅我的第一条评论)
  • 您使用的某些变量从未在您显示的代码(hdnPlainBody)中定义

其余的评论,我不太了解。

  

..我在其中添加了面板,添加了img,并且我在“列出所建议的项目”之前和之后显示和隐藏正在加载的图像,只有在加载可见的false后才会触发true

我现在将保留此答案,因为我相信它可以为您提供一些有价值的信息。但是,我知道这不会完全回答您的问题。请澄清其他内容和/或提出新问题。确保包含 all 所有我们需要的代码来重现问题并包含您想发生的事情。

祝你好运!

最终编辑:

现在您已经更新了问题并添加了新代码,我可以再次查看它。老实说,我有点迷茫。

  • 您现在调用了一个名为SaveAndGetSuggestedItemFromKenome的方法,该方法不存在。
  • 您仍然没有显示关于hdnPlainBodyhfdOrderRecordID的任何内容,它们在代码中都从未定义。
  • 您现在有了try-catch语句,在这种情况下,它们实际上没有任何意义。仍然有可能,但是我建议您阅读this question

对不起,但是我无法理解您的问题的描述:

  

问题是手动刷新页面并加载连续显示的图像后,将加载网格视图。

我认为最好是仔细阅读我告诉过的所有内容,调整代码并使用该代码提出新的问题。详细并以可理解的方式说明问题所在。这表示当前行为是什么,以及您期望得到的结果。
尽可能提供相关信息。