【问题标题】:use of timer causes HttpContext.Current to be null使用计时器会导致 HttpContext.Current 为空
【发布时间】:2013-09-06 07:16:21
【问题描述】:

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

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 变量的值)为空。

我应该使用其他方法来让它工作吗?

【问题讨论】:

标签: asp.net vb.net


【解决方案1】:

如前所述,HttpContext 应该为 null,因为 Timer_Elapsed 在不同的线程中被调用。但是你可以使用 System.Web.HttpRuntime.Cache 来传递文件名,缓存应该可以从所有线程访问。

【讨论】:

    【解决方案2】:

    HttpContext.Current 仅在您在处理传入线程的线程上调用它时为您提供所需的上下文。

    在此类线程之外调用它时,您会得到null。这符合您的情况,因为 Timer1_Elapsed 是在新线程上执行的。

    【讨论】:

      【解决方案3】:

      我应该使用其他方法来使其工作吗?

      几乎可以肯定,是的。 30 秒是很长的等待时间而不给用户任何反馈。

      向用户返回“尚无可用结果,但我们仍在寻找”页面可能会更好。通过添加合适的元标记,可以将该页面设置为 30 秒后自动刷新:

      <META HTTP-EQUIV="refresh" CONTENT="30">
      

      然后您会在服务器上获得一个新的请求/响应周期。并且暂时没有占用服务器资源。


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

      【讨论】:

        【解决方案4】:

        Timer 上的 Elapsed 事件将在 单独的线程上运行,因此当前上下文的预期行为为 null。

        您只能从同一个线程访问它。

        我应该使用其他方法来使其工作吗?

        是的,考虑到 ASP.NET 工作方式的复杂性,混合 ASP.NET 和线程通常不是一个好主意。就像已经提到的那样,在 30 秒内没有反​​馈并不是一个很好的 UX,最好让用户知道实际发生了什么。

        此外,您需要确定超时长度是否合适或是否需要超时。我不知道您的应用程序的性质,但我认为有一些外部方法可以让您的站点生成和获取文件。

        【讨论】:

          猜你喜欢
          • 2019-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-30
          相关资源
          最近更新 更多