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方法会遇到类似的问题吗?

C#:借用javascript的方法会不会有递归限制的问题

是的,您的代码最终会达到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中相同的逻辑。