我有一个解析输入文件的函数。
Private Function getSvSpelOdds(ByVal BombNo As Integer) As Boolean
Dim InputFileBase As String = HttpContext.Current.Application("InputFileBase")
strInputFile = InputFileBase & "PC_P7_D.TXT"
OddsReader = New StreamReader(strInputFile)
'some other code
End Function
如果文件不存在(getSvSpelOdds返回False),我想在30秒后重试。 为此,我使用计时器。
If Not getSvSpelOdds(y) Then
Timer1.Interval = 30000
End If
Private Sub Timer1_Elapsed(sender As Object, e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
getSvSpelOdds(y)
End Sub
问题是当计时器触发HttpContext.Current(用于获取gloal变量的值)时为null。
我应该使用其他方法来实现这一点吗?
答案 0 :(得分:1)
如前所述,HttpContext应为null,因为在不同的线程中调用了Timer_Elapsed。但您可以使用System.Web.HttpRuntime.Cache传递文件名,缓存应该可以从所有线程访问。
答案 1 :(得分:0)
HttpContext.Current
只会在处理传入线程的线程上调用它时为您提供所需的上下文。
在此类线程之外调用它时,您会得到null
。这符合您的情况,因为Timer1_Elapsed在新线程上执行。
答案 2 :(得分:0)
Timer上的Elapsed事件将在单独的线程上运行,因此当前上下文的预期行为为null。
您只能从同一个帖子访问它。
我应该使用其他方法来实现这一目标吗?
是的,考虑到ASP.NET工作原理的复杂性,混合ASP.NET和线程通常不是一个好主意。就像已经提到的那样,它不是一个很好的用户体验,在30秒内没有反馈,最好让用户知道实际发生了什么。
此外,您需要确定超时长度是否合适或是否需要超时。我不知道您的应用程序的性质,但我认为有一些外部方法可以生成文件并由您的网站提取。
答案 3 :(得分:0)
我应该使用其他方法来实现这一目标吗?
几乎可以肯定,是的。在没有向用户提供任何反馈的情况下等待30秒是很长的时间。
向用户返回“尚未提供结果,但我们仍在查找”页面可能会更好。通过添加合适的元标记,可以将该页面设置为在30秒后自动刷新:
<META HTTP-EQUIV="refresh" CONTENT="30">
然后您在服务器上获得新的请求/响应周期。并且在此期间没有捆绑服务器资源。
其他答案似乎解决了你问题的另一部分(关于为什么它在定时器回调中不起作用)