How do I handle async operations in Startup.Configure?

这一生的挚爱 提交于 2019-12-20 10:15:22

问题


In my ASP.NET 5 app, I want to load some data from Azure into a cache inside my Startup.Configure method. The Azure SDK exposes async methods exclusively. Typically, calling an async method is done via await inside an async method, like this:

public async Task Configure(IApplicationBuilder app, IMemoryCache cache)
{
    Data dataToCache = await DataSource.LoadDataAsync();
    cache.Set("somekey", dataToCache);

    // remainder of Configure method omitted for clarity
}

However, ASP.NET 5 requires that the Configure method returns void. I could use an async void method, but my understanding is that async void methods are only supposed to be used for event handlers (as per https://msdn.microsoft.com/en-us/magazine/jj991977.aspx among many others).

I was thinking that a better way to do this would be to call the async function without await, call Wait on the returned Task, then cache the results via the Task.Results property, like this:

public void Configure(IApplicationBuilder app, IMemoryCache cache)
{
    Task<Data> loadDataTask = DataSource.LoadDataAsync();
    loadDataTask.Wait();
    cache.Set("somekey", loadDataTask.Result);

    // remainder of Configure method omitted for clarity
}

Stephen Walther used a similar approach in a blog post earlier this year. However, it's unclear from that post if this is considered an acceptable practice. Is it?

If this is considered an acceptable practice, what - if any - error handling do I need? My understanding is that Task.Wait() will re-throw any exceptions thrown by the async operation and I haven't provided any mechanism to cancel the async operation. Is simply calling Task.Wait() sufficient?


回答1:


The example code in the blog you linked to was only using sync-over-async to populate a database with example data; that call wouldn't exist in a production app.

First, I'd say that if you truly need Configure to be asynchronous, then you should raise an issue with the ASP.NET team so it's on their radar. It would not be too difficult for them to add support for a ConfigureAsync at this point (that is, before release).

Second, you've got a couple of approaches to the problem. You could use task.Wait (or better yet, task.GetAwaiter().GetResult(), which avoids the AggregateException wrapper if an error does occur). Or, you could cache the task rather than the result of the task (which works if IMemoryCache is more of a dictionary than some weird serialize-into-binary-array-in-memory thing - I'm looking at you, previous versions of ASP.NET).

If this is considered an acceptable practice, what - if any - error handling do I need?

Using GetAwaiter().GetResult() would cause the exception (if any) to propagate out of Configure. I'm not sure how ASP.NET would respond would be if configuring the application failed, though.

I haven't provided any mechanism to cancel the async operation.

I'm not sure how you can "cancel" the setup of an application, so I wouldn't worry about that part of it.




回答2:


You can do some asynchronous work, but the method is synchronous and you cannot change that. This means you need synchronously wait for async calls to be completed.

You don't want to return from a Startup method if the startup is not finished yet, right? Your solution seems to be all right.

As for exception handling: If there's a piece of work that your application can't run properly without, you should let the Startup method fail (see Fail-fast). If it isn't something critical I would enclose the relevant part in a try catch block and just log the problem for later inspection.




回答3:


The answers in here do not always work correctly if your async code makes further async calls, especially if those are callbacks, then you may find the code deadlocks.

This has happens on numerous occasions for me and have used the Nito.AsyncEx with great effect.

using Nito.AsyncEx;

AsyncContext.Run(async () => { await myThing.DoAsyncTask(); });


来源:https://stackoverflow.com/questions/32257640/how-do-i-handle-async-operations-in-startup-configure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!