我有一个旧的数据访问库,我需要在我的ASP.NET MVC应用程序中使用,但是我很难将它带入MVC世界,因为许多服务器端操作都应该是异步的。我的数据访问库看起来像这样:
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 };
}
}
}
由我的MVC应用程序调用,如下所示:
public class MyUserStore : IUserStore<ApplicationUser>
{
private readonly MyOldDAL _dal = new MyOldDAL();
public async Task CreateAsync(ApplicationUser user)
{
await Task.Run(() => _dal.CreateUser(user.UserName));
}
}
在Task.Run()
中的方法出于某种原因失败之前,这是正常的。如果TaskStatus.Faulted
错误,我希望能够返回TaskResult.Success
,但我无法在线找到如何正确操作的示例 - 我所有的Google搜索结果都是如何使用Task<T>
接口不允许的IUserStore
。
对于记录,我希望我能改变MyOldDAL
- 它的目标是.NET 3.5,所以没有async
或{{1}那里!
答案 0 :(得分:3)
报告任务错误的正常方法是通过例外,因此您只需要自己进行转换:
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));
}
}
请注意,Task.Run
答案 1 :(得分:1)
注意:正如Stephen Cleary在回答中所说,Task.Run
原始答案(评论前):
您的CreateAsync
方法通常应该是这样的:
public async Task<TaskResult> CreateAsync(ApplicationUser user)
{
return await Task.Run(() => _dal.CreateUser(user.UserName));
}
但是,如果您无法从Task<TaskResult>
方法返回CreateAsync
......那么,根据定义,您无法从TaskResult
获取CreateAsync
。在这种情况下,您可以在本地存储结果:
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
}
或者使用TaskResult
有效负载引发事件,允许MyUserStore
的客户订阅此事件:
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);
}