英文:
Ajax call to get progress using IProgress
问题
这是您提供的代码的翻译:
我有2个ajax api调用,一个在一个长时间的过程中获取数据,另一个使用IProgress接口获取进度值,并每5秒执行一次。当进入调试器时,我可以看到值在ReportProgress中更新,并且这个值被设置为_generateRecipeCardsStatus属性。我的问题是,当调用getProgress() -> GeneratePrintRecipeCardsStatus时,属性_generateRecipeCardsStatus始终为零,我错在哪里?
谢谢
<script>
getData();
getProgress()
// 长时间的过程
function getData() {
const token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
headers: {
'X-Requested-With': 'XMLHttpRequest',
"X-ANTI-FORGERY-TOKEN": token
},
type: 'POST',
url: `@Url.Action("GeneratePrintRecipeCards", "MenuPrintout")?id=` + @Model.RecipeCardLabelId + `&menuHeaderId=` + @Model.MenuHeaderId,
success: function(response){
console.log(response)
const { errorMsg, progressValue } = response
inProgressEle.hide();
close.show();
if (errorMsg) {
toast(errorMsg, "error")
}
else if (progressValue > 0) {
console.log("进度值:" + progressValue);
}
else{
expand.hide()
collapse.hide()
statusEle.text("准备就绪");
completedEle.fadeIn()
}
}
});
}
// 获取进度
function getProgress() {
setInterval(function(){
$.ajax({
url: '@Url.Action("GeneratePrintRecipeCardsStatus", "MenuPrintout")',
type: "GET",
success: function (response) {
console.log(response)
$('#lblStatus').text(response)
}
})
}, 5000)
}
</script>
// 控制器
public class MenuPrintoutController : BaseController
{
private readonly IMenuLabelService _menuLabelService;
private int _generateRecipeCardsStatus;
private Progress<int> _progress;
public MenuPrintoutController(IMenuLabelService menuLabelService)
{
_menuLabelService = menuLabelService;
}
// 总是为零
public int GeneratePrintRecipeCardsStatus()
{
return _generateRecipeCardsStatus;
}
// 更新正常
private void ReportProgress(int progress)
{
_generateRecipeCardsStatus = progress;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GeneratePrintRecipeCards(int id, int menuHeaderId)
{
try
{
_progress = new Progress<int>(ReportProgress);
var data = await _menuLabelService.DoAsync(int menuHeaderId, _progress);
TempData.Put("PrintRecipeCards", data);
return Json(new { Success = true });
}
catch (Exception exp)
{
return Json(new { ErrorMsg = exp.Message });
}
}
}
// 服务
public interface IMenuLabelService
{
Task<object> DoAsync(int menuHeaderId, IProgress<int> progress);
}
public class MenuLabelService : IMenuLabelService
{
public async Task<object> DoAsync(int menuHeaderId, IProgress<int> progress)
{
var menuFoodItemsList = _context.FoodItemUnits
.Where(x => x.MenuSectionFoodItemUnits.Any(y => y.Menusection.MenuheaderId == menuHeaderId))
.Select(x => x.Fooditem)
.ToList();
var menuFoodItems = new List<PrintLabel>();
var donePointer = 0;
foreach (var menuFoodItem in menuFoodItemsList)
{
menuFoodItems.Add(menuFoodItem);
// ...
progress.Report((int)(++donePointer / (double)menuFoodItemsList.Count * 100));
donePointer++;
}
return menuFoodItems;
}
}
请注意,代码中的某些部分可能需要根据上下文和项目的具体要求进行进一步优化或调整。
英文:
I have 2 ajax api calls one fetches data in a long process and and other gets the progress value using IProgress interface and executes every 5 seconds. When hitting the debugger I can see the value updates in ReportProgress and this value gets set to _generateRecipeCardsStatus property. My issue is when calling getProgress() -> GeneratePrintRecipeCardsStatus the propety _generateRecipeCardsStatus is always zero where am I going wrong?
Thanks
<script>
getData();
getProgress()
// long process
function getData() {
const token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
headers: {
'X-Requested-With': 'XMLHttpRequest',
"X-ANTI-FORGERY-TOKEN": token
},
type: 'POST',
url: `@Url.Action("GeneratePrintRecipeCards", "MenuPrintout")?id=` + @Model.RecipeCardLabelId + `&menuHeaderId=` + @Model.MenuHeaderId,
success: function(response){
console.log(response)
const { errorMsg, progressValue } = response
inProgressEle.hide();
close.show();
if (errorMsg) {
toast(errorMsg, "error")
}
else if (progressValue > 0) {
console.log("progress value:" + progressValue);
}
else{
expand.hide()
collapse.hide()
statusEle.text("Ready");
completedEle.fadeIn()
}
}
});
}
// get progress
function getProgress() {
setInterval(function(){
$.ajax({
url: '@Url.Action("GeneratePrintRecipeCardsStatus", "MenuPrintout")',
type: "GET",
success: function (response) {
console.log(response)
$('#lblStatus').text(response)
}
})
}, 5000)
}
</script>
// controller
public class MenuPrintoutController : BaseController
{
private readonly IMenuLabelService _menuLabelService;
private int _generateRecipeCardsStatus;
private Progress<int> _progress;
public MenuPrintoutController(IMenuLabelService menuLabelServicee)
{
_menuLabelService = menuLabelService;
}
// Is always zero
public int GeneratePrintRecipeCardsStatus()
{
return _generateRecipeCardsStatus;
}
// Updates fine
private void ReportProgress(int progress)
{
_generateRecipeCardsStatus = progress;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GeneratePrintRecipeCards(int id, int menuHeaderId)
{
try
{
_progress = new Progress<int>(ReportProgress);
var data = await _menuLabelService.DoAsync(int menuHeaderId, _progress);
TempData.Put("PrintRecipeCards", data);
return Json(new { Success = true });
}
catch (Exception exp)
{
return Json(new { ErrorMsg = exp.Message });
}
}
}
// service
public interface IMenuLabelService
{
Task<object> DoAsync(int menuHeaderId, IProgress<int> progress);
}
public class MenuLabelService : IMenuLabelService
{
public async Task<object> DoAsync(int menuHeaderId, IProgress<int> progress)
{
var menuFoodItemsList = _context.FoodItemUnits
.Where(x => x.MenuSectionFoodItemUnits.Any(y => y.Menusection.MenuheaderId == menuHeaderId))
.Select(x => x.Fooditem)
.ToList();
var menuFoodItems = new List<PrintLabel>();
var donePointer = 0;
foreach (var menuFoodItem in menuFoodItemsList)
{
menuFoodItems.Add(menuFoodItem);
// ...
progress.Report((int)(++donePointer / (double)menuFoodItemsList.Count * 100));
donePointer++;
}
return menuFoodItems;
}
}
答案1
得分: 1
每个请求都会创建一个新的控制器,因此有两个不同的_generateRecipeCardsStatus
变量。
如果你只想支持单个服务器上的单个调用,可以将变量设为静态。
如果你想允许多次调用,那么你需要一种标识/查找机制。请注意,你还需要一种方法在状态过时(并且可能不再需要)时删除这些状态,因此这种查找不太像字典,而更像缓存。
如果你想将其部署到多个服务器上,那么你需要一个外部缓存,而不是将其保存在内存中。
英文:
A new controller is created for each request, so there are two different _generateRecipeCardsStatus
variables.
If you only want to support a single call on a single server, you can just make the variable static.
If you want to allow multiple calls, then you'll need some kind of identifier/lookup mechanism. Note that you will also want a way to remove the statuses when they're too old (and presumably no longer needed), so this lookup is less of a dictionary and more of a cache.
If you want to deploy this to multiple servers, then you'll need an external cache rather than keeping it in memory.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论