【问题标题】:HttpWebRequest.GetResponse Timeout issue when running from scheduled task on a server从服务器上的计划任务运行时出现 HttpWebRequest.GetResponse 超时问题
【发布时间】:2015-01-29 17:42:10
【问题描述】:

目前我有一个 .NET 应用程序,使用他们的 API 登录到 SalesForce。从这里我查询一个对象以提取报告信息并构建一个将导出文件的 URL。代码就是这样。

Dim request As HttpWebRequest
Dim response As HttpWebResponse
Dim stream as Stream
request = CType(WebRequest.Create(URL), HttpWebRequest)
request.Method = "GET"
request.Headers.Add("Cookie", "sid=" & header.sessionId)
response = CType(request.GetResponse(), HttpWebResponse)
stream = response.GetResponseStream()

我上面的 header.sessionId 是 SalesForce Session Header,它捕获我的会话以成功登录。

此应用程序在本地测试或在生产服务器(在 Visual Studio 2010 中)上运行时可以成功运行。我已将其设置为作为导致问题的计划任务运行。该任务设置为在服务器上以管理员帐户身份运行,如果手动启动(右键单击任务 -> 运行)或在运行时保持与服务器的连接,则可以工作。如果我断开与服务器的连接并且任务运行,我每次都会收到“System.Net.WebException:操作在 System.Net.HttpWebRequest.GetResponse() 处超时”错误。然后手动登录并启动应用程序。

如上所述,这设置为作为管理员帐户运行,并且我已为该帐户提供了完全的安全控制权。我没有选中“仅在登录时运行”,也没有将其设置为仅在空闲时运行。

据我所知,Web 请求的默认超时时间是 100,000 毫秒或 100 秒。在达到该限制之前,此任务会超时。就在显​​示的代码之前,我检查以确认我的会话仍然有效,如果不是,则更新我的会话。这个超时总是发生在第一个尝试下载的报告上,但是当手动运行时,我可以在 2 分钟内下载大约 25 个报告。

有什么想法吗?

【问题讨论】:

  • ...您是否尝试过延长超时时间?
  • 我尝试了多个不同的超时,在所有情况下超时都发生在达到限制之前。
  • 等一下,当你没有达到超时时它会给你一个超时错误?也许您需要添加一个保持活动状态。
  • KeepAlive 的默认值为 True。不过我会尝试添加它。
  • 我不知道这是否是问题所在,但在执行此类工作时我总是添加 300 的保活值:request.Headers.Add("Keep-Alive", "300")。您是否也尝试过使用 Telerik Fiddler telerik.com/fiddler 等 Web 调试代理来查看服务器上实际发生的情况?

标签: vb.net salesforce httpwebrequest scheduled-tasks


【解决方案1】:

根据我之前的评论,似乎涉及到需要用户登录才能成功请求的代理。

您的回复:

我们使用通过单点登录为用户工作的互联网安全网络代理。基本上,只要用户在允许或阻止流量之前尝试访问幕后站点,该工具就会提取用户的网络凭据。问题是一旦管理员帐户断开连接,此 Web 代理将尝试从登录用户那里收集凭据,但什么也找不到。然后该请求将被拒绝。这就是为什么任何登录的用户都可以工作但每隔一段时间就会失败的原因。

【讨论】:

    【解决方案2】:

    这不是“答案”,但我创建了一个相当粗糙的 HttpWebRequest 测试应用程序并将其设置为以另一个未登录 Windows 7 的用户身份运行(对不起,我无权访问服务器自动柜员机)。测试在我尝试的每一种方式下都完美无缺。可能是因为 Windows 7 做的事情与(您试图让它在哪个操作系统上运行?)不同,或者实际上是您的代码中的某些东西导致了问题。由于此代码对我有用,我建议您尝试一下,至少消除您的代码问题。

    创建一个新的 vb.net 应用程序并确保删除所有表单并创建一个模块 (Module1) 并在其中添加此代码:

    Imports System.Net
    Imports System.IO
    
    Module Module1
        Const sUserAgent As String = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
        Const sMainURL As String = "http://www.stackoverflow.com/"
        Private gsLogFile As String = System.IO.Path.Combine(Application.StartupPath, "logfile.txt")
    
        Sub Main()
            StartScrape()
        End Sub
    
        Private Sub StartScrape()
            Try
                GetMethod(sMainURL)
                SaveTextToFile("Finished", gsLogFile)
            Catch ex As Exception
                SaveTextToFile("Error: " & ex.Message, gsLogFile)
            End Try
        End Sub
    
        Private Function GetMethod(ByVal sPage As String) As Boolean
            Dim req As HttpWebRequest
            Dim resp As HttpWebResponse
            Dim stw As StreamReader
            Dim bReturn As Boolean = True
    
            Try
                req = HttpWebRequest.Create(sPage)
                req.Method = "GET"
                req.AllowAutoRedirect = False
                req.UserAgent = sUserAgent
                req.Accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
                req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
                req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
                req.Headers.Add("Keep-Alive", "300")
    
                resp = req.GetResponse        ' Get the response from the server 
    
                If req.HaveResponse Then
                    resp = req.GetResponse        ' Get the response from the server 
                    stw = New StreamReader(resp.GetResponseStream)
                    stw.ReadToEnd()    ' Read the response from the server, but we do not save it
                Else
                    SaveTextToFile("No response received from host " & sPage, gsLogFile)
                    bReturn = False
                End If
            Catch exc As WebException
                SaveTextToFile("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, gsLogFile)
                bReturn = False
            End Try
    
            Return bReturn
        End Function
    
        Public Function SaveTextToFile(ByVal strData As String, ByVal FullPath As String) As Boolean
            Dim bAns As Boolean = False
            Dim objReader As IO.StreamWriter
    
            Try
                objReader = New IO.StreamWriter(FullPath, System.IO.File.Exists(FullPath))
                objReader.Write(Format(Now, "dd-MMM-yyyy hh:mm:ss tt") & " - " & strData)
                objReader.Close()
                bAns = True
            Catch Ex As Exception
    
            End Try
            Return bAns
        End Function
    End Module
    

    一个日志文件logfile.txt 将在执行完成后创建在与exe 相同的目录中。如果出现错误,它将被记录到文件中,最后会显示“已完成”并带有时间戳。我在任务计划程序中使用不同的选项以几种不同的方式运行它,并且每次我只有一个日志条目显示“已完成”。如果您决定对此进行测试,请报告您的结果,就好像此测试失败我肯定会说您的计划任务有问题。

    【讨论】:

    • 明天我会试一试。我已将我的请求放入 While 中,并将重试 bool = 设置为 False。如果我遇到超时,我会设置 retry = True 并增加一个计数器。在第三次失败时,我接受超时并向自己发送一封错误电子邮件。我记录每个失败(带有数字)以及带有时间和日期戳的最终失败。将使用我的更改和日志文件转储编辑我的原始帖子。
    猜你喜欢
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多