Make WebMethod Async Webform
Asked Answered
T

1

5

I have tons of [WebMethod] in whole application and I want all my [WebMethod] to be async. I decorated all my[WebMethod] signatures with async and await keywords and then I run my app. It didn't work out as expected. Let say I have following code

Code Behind

[WebMethod]
public static async Task<List<XXX>> GetXXX()
{
    return await new BusinessLogic().GetXXX().ConfigureAwait(false);
}

Business Layer

    internal async Task<List<XXX>> GetXXX()
    {
        var obj = await objDAL.GetXXX().ConfigureAwait(false);
        List<XXX> listDO = new List<XXX>();
        foreach (var item in obj)
        {
            listDO.Add(new Countries
            {
                XXXName = item.name,
                XXXID = item.id
            });
        }
        return listDO;

objDAL.GetXXX

    internal async Task<List<tblXXX>> GetXXX()
    {
        using (ABCEntities ctx = new ABCEntities())
        {
            return await ctx.tblXXX.ToListAsync().ConfigureAwait(false);
        }
    }

I have put debuggers in the whole path the code above come to return await ctx.tblXXX.ToListAsync(); and then the debugger loses control and the system became non-responsive. I have found old solutions that doesn't use the power of async and await.

Question is how I can make my WebMethod Function asyc.

Thanks

Thursday answered 30/1, 2017 at 10:55 Comment(4)
how many records are therein table, as you are loading all records in memory,Counterscarp
and as your calling method is async, you don't need to use Task.Run just this would work: return await new BusinessLogic().GetXXX();Counterscarp
@EhsanSajjad Thanks for the comment. Particularly for XXX I got 249 entries in the DB but that not the question. I tested it with different Table but all produced the same output and that is no output.Slider
Adding ConfigureAwait(false) to every await function does the job whenever the page is loaded for the first time, but when the page is requested again the client never gets the page and client remains in continuous wait.Slider
A
0

Before you can use async/await, you'll need to run on .NET Framework 4.5 or newer, and set httpRuntime.targetFramework to 4.5 or newer. If you cannot upgrade to .NET 4.5 yet, then full stop: you cannot use async or await at all.

Then, you can use a standard APM-over-TAP wrapper pattern, as such:

private static async Task<List<XXX>> GetXXXAsync()
{
  return await new BusinessLogic().GetXXX().ConfigureAwait(false);
}

[WebMethod]
public IAsyncResult BeginGetXXX(AsyncCallback callback, object state)
{
  var tcs = new TaskCompletionSource<List<XXX>>(state);
  var task = GetXXXAsync(arg);
  ExtractResultWhenComplete();
  return tcs.Task;

  async void ExtractResultWhenComplete()
  {
    try { tcs.TrySetResult(await task); }
    catch (Exception ex) { tcs.TrySetException(ex); }
    callback?.Invoke(tcs.Task);
  }
}

[WebMethod]
public List<XXX> EndGetXXX(IAsyncResult result)
{
  return ((Task<List<XXX>>)result).GetAwaiter().GetResult();
}
Anchoress answered 14/6, 2023 at 14:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.