代码契约只是像处理任何其他变量那样处理任务,而不是异步地等待结果。因此,以下方案将不起作用,并导致合同异常,因为在方法返回时,它是一个不完整的任务,并且结果将不会在该时间点设置。以下方案是否有任何合理的解决方法?
public Task LoadAppModel()
{
Contract.Ensures(app.User != null);
Contract.Ensures(app.Security != null);
Contract.Ensures(app.LocalSettings != null);
return Task.WhenAll(
store.GetUserAsync().ContinueWith(t => { app.User = t.Result; }),
store.GetSecurityAsync().ContinueWith(t => { app.Security = t.Result; }),
store.GetLocalSettingsAsync().ContinueWith(t => { app.LocalSettings = t.Result; }));
}
任何建议将不胜感激。 :)我宁愿不打破合同模式。
答案 0 :(得分:5)
代码合同与async
不能很好地结合在一起,因此您无法真正使用Contract.Ensures
。
但是有一种解决方法。您可以将方法从Task
- 返回方法更改为async
方法(无论如何都更干净)并改为使用Contract.Assume
:
public async Task LoadAppModel()
{
var userTask = store.GetUserAsync();
var securityTask = store.GetSecurityAsync();
var settingsTask = store.GetLocalSettingsAsync();
await Task.WhenAll(userTask, securityTask,settingsTask);
app.User = userTask.Result;
app.Security = securityTask.Result;
app.LocalSettings = settingsTask.Result;
Contract.Assume(app.User != null);
Contract.Assume(app.Security != null);
Contract.Assume(app.LocalSettings != null);
}