-1

I want to show list of items asynchronously, I'm doing like below but i'm not sure it is working properly or not. can you guys help me out, is this the proper way?

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;
   }
}

Edit: Now I'm using below code it is working and I'm saving and getting data by SaveAndGetSuggestedItem() method. it will take time to save data in database, in the mean time i want to show loading image once it is completed loading image should hide and data should populate in grid-view , I've added code below, but problem is grid-view will load after page refreshed by manually and loading image showing continuously.

    /// <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;
        }
    }

Front page(View):

 <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>
PK-1825
  • 1,431
  • 19
  • 39
  • 5
    What do you expect to happen here? Btw don't use `async void` unless you're writing an event handler. – Joelius Aug 12 '19 at 07:31
  • my whole page has many postback events, in that i want to load gridview asynchronously. on click event GetSuggestedItemsFromService this mehtod will call and save the data after that i will bind it to the gridview. this will takw around 20 to 30sec so if apply asyn await i can do other work in the mean while – PK-1825 Aug 12 '19 at 07:37
  • 1
    Did you take a look at the [microsoft guide](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/)? I think you'd benefit from looking into `async/await` by reading through some articles and tutorials first. Also when asking a question please include what's happening currently and what you want to happen instead. – Joelius Aug 12 '19 at 07:46
  • private async void GetSuggestedItemsFromService()-> private async Task GetSuggestedItemsFromService() – dexiang Aug 12 '19 at 08:04
  • It would be better if you make `OHDService.SaveSuggestedItems(...)` also asyncable – Circle Hsiao Aug 12 '19 at 08:08
  • What do you want to achieve? Do you want to make the page load faster, or to preserve server resources for maximum scalability? – Theodor Zoulias Aug 12 '19 at 11:02
  • while processing i want work on other thing in same page. – PK-1825 Aug 12 '19 at 11:29

1 Answers1

3

Okay so a few things.

  • Your SuggestedItemAsync method isn't async and it returns multiple items so it should be called SuggestedItems. Since it's good to have an idea of what it has to do with "SuggestedItems", I would also consider adding Get in front just like you did with the other method. So GetSuggestedItems would be the name I'd choose.
  • Don't use async void unless you're using the method as an event-handler (backwards compatibility). Use async Task instead if there isn't a return type.
  • Your GetSuggestedItemsFromService method is async so you should call it GetSuggestedItemsFromServiceAsync.
  • I don't know what OHDWebService is but you should check if it implements IDisposable and if so, wrap it in a using-statement.

I assume you just want to start the method SuggestedItems asnychronouly because it takes long. You can do that with Task.Run which is much better than creating a new task explicitly.

Here's how I would rewrite your code:

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;
    }
}

EDIT:
So after going through some comments there are some more things to mention.

  • The GetSuggestedItems method seems to also save some values so maybe SaveSuggestedItems or SaveAndGetSuggestedItems would be a more appropriate name.
  • The GetSuggestedItems method uses hdnPlainBody which is not defined (or you didn't show the code where it is). Did you mean to make this a parameter? If so, it would have to be some class/struct which has a Value property. But in the GetSuggestedItemsFromServiceAsync method you call the GetSuggestedItems method with a string as parameter. Is there an overload that accepts string which you didn't show us?

And finally to the actual question. I will include your comment here it's clear what we're talking about:

SuggestedItemAsync will save data and return list but when cursor enter await it wont allow to run next line but data is saving in db.

What I get from this is that you expect the insertion and getting of the data to go row by row, asynchronously.
For that to be possible, the implementation of OHDService.SaveSuggestedItems would have to be async and support that. In your code it's not async so the only way you could achieve this row by row behaviour would be to iterate over the data you're inputting and doing so asynchronously, inserting one row at the time. You have not provided enough context for me to be able to help you with that unfortunately.
Also since you mentioned that it already takes (too) long, wrapping this just to be async might not be a good idea since it will take even longer.

I think you should really provide more information. We can't really help you because:

  • You call a parameterless method with a string as parameter and didn't mention anything about that
  • You didn't specify what behaviour you expect (see my first comment)
  • You use some variables that are never defined in the code you showed (hdnPlainBody)

Also the rest of your comment, I don't really understand.

.. I have added panel within i've added img and i'm showing and hiding loading image before and after "List suggestedItems" only true is working after loading visible false is not firing

I will leave this answer now as I believe it has some valuable information for you. However I understand that this is not going to fully answer your question. Please clarify the other stuff and/or ask a new question. Make sure to include all the code we need to reproduce the problem and to include what you want to happen.

Good luck!

Final Edit:

Now that you've updated the question and added new code I can look at it again. Honestly, I'm kind of lost.

  • You now call a method called SaveAndGetSuggestedItemFromKenome which doesn't exist.
  • You still did not show anything about hdnPlainBody and hfdOrderRecordID which are both never defined in your code.
  • You now have try-catch statements which don't really make sense in this case. It's still a possibility but nevertheless I'd advise you to read this question.

Also, I'm sorry, but I can't make sense of the description of your problem:

problem is grid-view will load after page refreshed by manually and loading image showing continuously.

I think it's best if you go through all the things I've told you, adjust your code and ask a new question with that code. Explain in detail and in an understandable manner what the issue is. This means what the current behaviour is and what you'd expect instead.
Provide as much relevant information as possible.

Joelius
  • 3,839
  • 1
  • 16
  • 36
  • `GetSuggestedItems()` does not accept the parameter, and you are passing the parameter as `GetSuggestedItems(Request["OrderRecordID"].ToString());`. – User_4373 Aug 12 '19 at 09:12
  • The original `SuggestedItemAsync` calls `SaveSuggestedItems`, so I am not sure that putting `Get` in front would totally clear up what it does. It seems to do a Save that returns the list of what was saved, which I would not describe as a `Get` operation. – Peter B Aug 12 '19 at 09:15
  • SuggestedItemAsync will save data and return list, – PK-1825 Aug 12 '19 at 09:46
  • but when cursor enter await it wont allow to run next line but data is saving in db. I have added panel within i've added img and i'm showing and hiding loading image before and after "List suggestedItems" only true is working after loading visible false is not firing – PK-1825 Aug 12 '19 at 09:48
  • @User_4373 good catch, I missed that one. @PeterB it obviously returns data so get isn't a bad choice. Of course it would be better if it was `SaveAndGet` or something like that but I don't know anything about that `OHDService`. – Joelius Aug 12 '19 at 15:30
  • @PK-1825 No, in that case it's impossible. That would require the method which actually gets (or saves or whatever) the data to be implemented with `async` so it could return after each row. If that's not the case you do it row by row if that is the only method you can use to get the data. Unless you reimplement that method yourself or implement some wrapper which iterates the data but that would probably be even less performant. – Joelius Aug 12 '19 at 15:33
  • @Joelius Thank you for taking time to answer. I have updated my code above, please take a look at it – PK-1825 Aug 13 '19 at 04:29