C#:借用javascript的方法会不会有递归限制的问题
本文关键字:递归 问题 不会有 方法 借用 javascript 会不会 | 更新日期: 2023-09-27 18:24:19
想知道javascript中可能使用的方法是否可以在C#中使用。
在javascript应用程序中,当必须一个接一个地发出大量web请求时,UI可以通过避免for循环而使用堆栈(数组)和事件来保持响应。下一个URL将从成功事件处理程序中的数组中弹出,它将继续发出另一个请求,直到堆栈为空。在带有堆栈的C#中可以采取类似的方法吗?以下内容合法吗?
urlStack .... // stack of urls
myRequestMaker = new WebRequestMaker(); // my custom object
myRequestMaker.ResponseReceived += (s,e) =>
{
// e contains info whether the request succeeded, failed, or timed out
url = pop another url from urlStack if it's not empty
(s as WebRequestMaker).MakeWebRequest(url);
}
url = pop first url from urlStack
myRequestMaker.MakeWebRequest(url);
(请求超时时,WebRequestMaker对象也会引发ReponsReceived事件,BTW)
在javascript中,使用这种方法可以达到最大递归限制,为了避免这种情况,可以将在成功事件处理程序中进行的方法调用封装在SetTimeout中。在ResponseReceived事件处理程序中调用myRequestMaker的MakeWebRequest方法会遇到类似的问题吗?
是的,您的代码最终会达到StackOverflowException
。您可以使用异步运行代码的System.Task
类来模拟setTimeout
行为:
myRequestMaker.ResponseReceived += (s,e) =>
{
// e contains info whether the request succeeded, failed, or timed out
url = pop another url from urlStack if it's not empty
Task.Run(() => (s as WebRequestMaker).MakeWebRequest(url));
}
(当然,你的urlStack现在应该是并发的,以避免比赛条件)
最理想的情况是,您不会使用上面的代码,而是实现一个MakeWebRequestAsync
方法,该方法可以异步完成您的工作。.Net中大多数内置的长时间运行/blockin方法(例如从/到流的读取和写入)已经实现了这样的方法,因此如果您的WebRequestMaker
实际上使用的是System.Net.WebClient
,则可以调用异步版本。有关任务和async/await的更多信息可以在MSDN中找到。
是的,每个函数调用都会被推送到调用堆栈,并在完成时弹出。您提到的错误是在调用堆栈已满时触发的,而不是在javascript中,在大多数语言中(事实上,我不知道有没有)。
您应该在这里应用与在Javascript中相同的逻辑。