使用timer会导致HttpContext.Current为null

时间:2013-09-06 07:16:22

标签: asp.net vb.net

我有一个解析输入文件的函数。

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。

我应该使用其他方法来实现这一点吗?

4 个答案:

答案 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">

然后您在服务器上获得新的请求/响应周期。并且在此期间没有捆绑服务器资源。


其他答案似乎解决了你问题的另一部分(关于为什么它在定时器回调中不起作用)