简体   繁体   中英

Async call on WCF resource

I am building a WCF service and I would need a bit of clarification regarding building async methods.

The functionality is supposed to be that when a request arrives, it contains the authentication information in the form of an authorizationToken, which gets checked and if authorization passed, then the actual functionality is executed.

Firstly, Service1.cs contains this method:

 public async Task<string> CreateClass(string name, int departmentId)
    {
        Class result = null;
        bool authResult = await System.Threading.Tasks.Task.Run(() =>
        {
            return authCtr.AuthenticateToken();
        });
        if (authResult)
        {
            result = await System.Threading.Tasks.Task.Run(() =>
            {
                return classCtr.CreateClass(name, departmentId);
            });
        }
        return result != null ?
            JsonConvert.SerializeObject(result, Formatting.Indented) :
            string.Format(response.StatusCode + "," + response.StatusDescription);
    }

Both methods AuthenticateToken() and CreateClass() are synchronous in this example, and they are responsible for Create and Read DB operation on the respective tables. After reading around more I thought of modifying the two methods to be async and modify the previous code, however after reading more and more, confusion hit and I can't decide which way is better/correct. If I were to choose, then I would go with rewriting all the methods to be async and call them in the service as:

public async Task<string> CreateClass(string name, int departmentId)
    {
        Class result = null;
        if(await authCtr.AuthenticateToken())
        {
            result = await classCtr.CreateClass(name, departmentId);
        }
        return result != null ?
            JsonConvert.SerializeObject(result, Formatting.Indented) :
            string.Format(response.StatusCode + "," + response.StatusDescription);
    }

So question1: are any of these ways are actually asynchronous, or it is just a total mess?

Question2: if I am to change the controller methods async, would it suffice to modify them so that they look like this:

return await System.Threading.Tasks.Task.Run(() =>
{
        //DO DB STUFF
}

If you want to write your code async then you need to really go down to the last level of actual .net framework itself, eg SqlCommand.ExecuteReaderAsync for ADO.Net (there are corresponding wrappers in all major ORMs).

This will give you the benefit of non-blocking invocations, meaning that the thread that is servicing the WCF action will be freed until such time as the IO returns the data. If you wrap your calls in Task.Run() you are essentially using a general-purpose threadpool in your app domain, so you can't benefit from the framework optimising the threads the same way it does with a full await .

In essence: yes, if you want to use WCF fully asynchronously, use the DB access with await . Otherwise, do everything synchronously without Task.Run() to avoid thread waiting and simply return Task.FromResult() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM