这里的想法是同时运行一些长时间运行的方法,一次运行5个。 当其中15个完成时(3个5个块),我应该从控制器方法返回。
问题在于它太早返回。通常它会在第一个5块之后返回,但我已经看到它从第二个块的中间返回。
^ - 我在所有return
语句中都有断点,但这些都没有被击中。我知道它返回,因为我从Javascript调用它并在我的浏览器中有一个断点。返回数据是一个空字符串。在对另一个问题提出建议之后 - 我添加了override void Dispose(..)
以查看是否会受到影响,但事实并非如此。
然后我在我的Global.asax.cs中的所有事件中放置了断点,例如在Application_Error
,Session_End
和Application_End
中,但是这些事件在过早的回归中不会受到影响无论是。我还在ActionFilterAttribute
事件的OnActionExecuted
中添加了一个断点,但这并没有被击中!我也安装了elmah,通常会发现错误。我无法找到我的代码返回getJson()
来电的位置。
对于块中的每个项目,LongRunning方法每个运行大约需要30秒。 我可以将块数从5增加(或减少)到10,并且在10完成后它仍然会返回。
我尽可能地减少了代码,以清楚地表达问题:
[HttpGet]
[Route("TestAPI/RunTest")]
public async Task<IHttpActionResult> RunTest(bool reload, DateTime period)
{
if (reload)
{
await BuildNewDataTest(period);
// Also tried:
// await BuildNewDataTest(period).ContinueWith((x) => { results = _myUoW.GetDataTest(period); });;
}
return Ok(_myUoW.GetDataTest(period));
// return Ok(results);
}
private async Task<bool> BuildNewDataTest(DateTime period)
{
// DoSomeStuff...
DateTime oldDate = DateTime.Now.AddDays(-30);
AddStuffToDatabase();
List<Task> concurrentRuns = new List<Task>();
for (int i = 0; i < 15; i += 5)
{
concurrentRuns.Clear();
List<MyType> block = fullList
.Skip(i)
.Take(5).ToList();
block.ForEach(x => concurrentRuns.Add(RunStuffAsync(period, oldDate, x.IsOpen)));
await Task.WhenAll(concurrentRuns);
}
return true;
}
private async Task<bool> RunStuffAsync(DateTime period, DateTime prevDate, bool isOpen)
{
// DoSomeStuff...
await Task.Run(() =>
{
_myUoW.RunSomeLongRunningProcess(longRunningID, period);
return true;
});
return false;
}
private void AddStuffToDatabase()
{
_myUoW.CreateNewEntry(...);
}
在我的Javascript断点被点击后,代码继续运行 - 所以我的所有15个进程都完全运行,return Ok(..)
的断点被点击。
调用JS是:
$.getJSON('TestAPI/RunTest', { reload: self.reload(), period: self.period() }, function (data) {
var myData = JSON.parse(data);
self.myReturnedData(myData);
createDataTable(myData);
});
感谢您的帮助。