I have a old data access library that I need to use in my ASP.NET MVC application but I'm having trouble bringing it into the MVC world where many server-side operations are expected to be asynchronous. My data access library looks a like this:
public class MyOldDAL
{
public TaskResult CreateUser(string userName)
{
try
{
// Do user creation
return new TaskResult { Success = true, Message = "success" };
}
catch (Exception ex)
{
return new TaskResult { Success = false, Message = ex.Message };
}
}
}
And is called by my MVC application like this:
public class MyUserStore : IUserStore<ApplicationUser>
{
private readonly MyOldDAL _dal = new MyOldDAL();
public async Task CreateAsync(ApplicationUser user)
{
await Task.Run(() => _dal.CreateUser(user.UserName));
}
}
This is fine until the method in Task.Run()
fails for some reason. I'd like to be able to return TaskStatus.Faulted
if TaskResult.Success
is false but I can't find an example online on how to do it properly - all my Google searches turn up is how to use Task<T>
which the IUserStore
interface doesn't permit.
For the record, much as I'd like to I can't change MyOldDAL
- it's targeting .NET 3.5 so no async
or await
there!
The normal way to report errors from tasks is via exceptions, so you'll just need to do that transformation yourself:
public class MyUserStore : IUserStore<ApplicationUser>
{
private readonly MyOldDAL _dal = new MyOldDAL();
public Task CreateAsync(ApplicationUser user)
{
var result = _dal.CreateUser(user.UserName);
if (result.Success)
return Task.CompletedTask;
return Task.FromException(new InvalidOperationException(result.Message));
}
}
Note that Task.Run
should not be used on ASP.NET.
Note: As Stephen Cleary noticed in his answer, Task.Run
should not be used on ASP.NET.
Original answer (before comments): Your CreateAsync
method should normally be like this:
public async Task<TaskResult> CreateAsync(ApplicationUser user)
{
return await Task.Run(() => _dal.CreateUser(user.UserName));
}
But if you can't return Task<TaskResult>
from CreateAsync
method... well, than you can't obtain TaskResult
from CreateAsync
by definition. In that case you can store result locally:
private TaskResult taskResult;
public async Task CreateAsync(ApplicationUser user)
{
var result = await Task.Run(() => _dal.CreateUser(user.UserName));
this.taskResult = result;
// process taskResult wherether you need
}
Or raise event with TaskResult
payload, allowing client of MyUserStore
to subscribe to this event:
public event EventHandler<TaskResult> TaskCompleted;
public async Task CreateAsync(ApplicationUser user)
{
var result = await Task.Run(() => _dal.CreateUser(user.UserName));
this.OnTaskCompleted(result);
}
private void OnTaskCompleted(TaskResult result)
{
this.TaskCompleted?.Invoke(this, result);
}
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.