我有Layout
个@RenderBody
部分和index
页面。我的索引页面有一个长时间运行的进程,我希望它在不等待DoSomeAsyncStuff
的情况下呈现视图。下面的代码看起来接近我想要的但问题是我的模型在传递给视图时它的属性为null:
public ActionResult Index()
{
MyModel model = new MyModel();
Task.Run(() => DoSomeAsyncStuff(model));
return View(model);
}
private async void DoSomeAsyncStuff(MyModel model)
{
await Task.Delay(20000);
model.Name = "Something";
//Assigning other model properties
}
在我看来,我得到了NullReferenceException
和Value cannot be null
错误,当然这是因为我的模型的属性仍未填充DoSomeAsyncStuff
方法:
<table>
<tr>
<th colspan="3">
@Model.Products.Select(c => c.Date).FirstOrDefault()
</th>
</tr>
@foreach (var item in Model.Products)
{
<tr>
<td>
@item.Title
</td>
<td>
@item.Price
</td>
</tr>
}
</table>
答案 0 :(得分:4)
您尚未展示您的模型,因此这将主要是伪代码。首先,将长期运行的东西移动到另一个动作:
public ActionResult Index()
{
var model = new MyModel();
return View(model);
}
public async Task<ActionResult> DoSomeAsyncStuff()
{
var model = new MyModel();
await Task.Delay(20000);
model.Name = "Something";
//Assigning other model properties
return PartialView("_InnerView", model);
}
模型绑定的所有内容都应该在部分视图中(我在这里调用_InnerView.cshtml
)。父视图应该只有一个占位符或加载小部件,其中模型绑定标记当前位于:
<div id="load-with-ajax">
Please wait. Loading...
</div>
然后,在页面的某个地方,在你的jQuery引用之后(我假设你正在使用jQuery或者愿意),添加如下内容:
<script>
$(function(){
$('#load-with-ajax').load('@Url.Action("DoSomeAsyncStuff")');
});
</script>
答案 1 :(得分:0)
您需要对方法应用async和await。这将确保模型在传递到视图时填充。
$input="/opt/lampp/htdocs/images/fish5.flv";
$time = shell_exec("ffmpeg -i $input 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//");
唯一的另一种选择是在两次调用中执行此操作。
public async Task<ActionResult> Index()
{
var model = new MyModel();
await DoSomeAsyncStuff(model);
return View(model);
}
private async Task DoSomeAsyncStuff(MyModel model)
{
await Task.Delay(20000);
model.Name = "Something";
//Assigning other model properties
}
无论哪种方式为了确保填充模型,您都必须等待异步方法返回。第二种方法可能会被调整到更接近你正在寻找的东西。