我在mvc 4 app中有一个控制器动作:
public ActionResult Index()
{
GetStartedModel gsModel = new GetStartedModel();
return View(gsModel);
}
和ViewModel:
public class GetStartedModel
{
public IEnumerable<SelectListItem> listA { get; set; }
public IEnumerable<SelectListItem> listB { get; set; }
public GetStartedModel()
{
TestDataWebServiceHelper service = new TestDataWebServiceHelper();
this.GetData(service);
}
private async void SetData(TestDataWebServiceHelper service)
{
listA = await this.SetListA(service);
listB = await this.SetListB(service);
}
private async Task<IEnumerable<SelectListItem>> SetListA(TestDataWebServiceHelper service)
{
List<String> rawList = new List<String>();
rawList = await service.GetValuesAsync("json");
return rawList.Select(x => new SelectListItem { Text = x, Value = x });
}
private async Task<IEnumerable<SelectListItem>> SetListB(TestDataWebServiceHelper service)
{
List<String> rawList = new List<String>();
rawList = await service.GetValuesAsync("json");
return rawList.Select(x => new SelectListItem { Text = x, Value = x });
}
}
当我调用此控制器操作时,我收到以下错误:
此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为&lt;%@ Page Async =“true”%&gt ;.
所以,问题:
答案 0 :(得分:5)
您的代码中存在两个问题:
您不应该像这样构造函数启动async void
操作。实际上,您通常不应该从构造函数启动任何async
操作,也不应该使用async void
方法(事件处理程序除外)。
我认为在你的情况下,async
工厂方法而不是构造函数最有意义:
private GetStartedModel()
{}
public static async Task<GetStartedModel> Create()
{
var service = new TestDataWebServiceHelper();
var result = new GetStartedModel();
listA = await result.SetListA(service);
listB = await result.SetListB(service);
return result;
}
有关详细信息,请参阅Stephen Cleary's post on async
constructors。
您还需要让控制器操作async
:
public async Task<ActionResult> Index()
{
var gsModel = await GetStartedModel.Create()
return View(gsModel);
}
答案 1 :(得分:0)
关于“异步”的一些注意事项如下:
Task
或Task< return-type >
。现在回答您的问题,
您应该将此代码放在ViewModel中:
private async void SetData(TestDataWebServiceHelper service)
{
listA = await this.SetListA(service);
listB = await this.SetListB(service);
}
private async Task<IEnumerable<SelectListItem>> SetListA(TestDataWebServiceHelper service)
{
List<String> rawList = new List<String>();
rawList = await service.GetValuesAsync("json");
return rawList.Select(x => new SelectListItem { Text = x, Value = x });
}
private async Task<IEnumerable<SelectListItem>> SetListB(TestDataWebServiceHelper service)
{
List<String> rawList = new List<String>();
rawList = await service.GetValuesAsync("json");
return rawList.Select(x => new SelectListItem { Text = x, Value = x });
}
然后你应该在需要时给它打电话。
(希望这会有所帮助......)