Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用HttpWebResponse重新连接到后台工作程序内部的网站?_C#_.net_Xml - Fatal编程技术网

C# 使用HttpWebResponse重新连接到后台工作程序内部的网站?

C# 使用HttpWebResponse重新连接到后台工作程序内部的网站?,c#,.net,xml,C#,.net,Xml,我目前面临的问题有点微妙,因为我正在使用C夏普的后台工作人员24/7天连接网站。主要的问题是,数据提供者(网站)偶尔会断开连接,我的后台工作人员无所事事。一旦网站的连接中断,我需要重新建立它的连接。目前这似乎很困难 我想创建一个无限循环,在一个单独的线程中检查HttpWebResponse。然而,这使得事情变得更加复杂,因为将变量从一个线程传递到另一个线程并不能简化这个问题 我要寻找的是一些使用后台工作类的本机解决方案。我想到的一件事是,我可以检查HttpWebResponse以知道何时重新连接

我目前面临的问题有点微妙,因为我正在使用C夏普的后台工作人员24/7天连接网站。主要的问题是,数据提供者(网站)偶尔会断开连接,我的后台工作人员无所事事。一旦网站的连接中断,我需要重新建立它的连接。目前这似乎很困难

我想创建一个无限循环,在一个单独的线程中检查HttpWebResponse。然而,这使得事情变得更加复杂,因为将变量从一个线程传递到另一个线程并不能简化这个问题

我要寻找的是一些使用后台工作类的本机解决方案。我想到的一件事是,我可以检查HttpWebResponse以知道何时重新连接。在BackgroundWorker_DoWork函数中放置类似的内容:

if (Response.StatusCode != System.Net.HttpStatusCode.OK)
{
   //reconnect
}
然而,我对后台工作者类非常陌生,在后台工作者代码中找不到无限循环的位置

我假设BackgroundWorker_DoWork函数中的“do while”循环可能是一个地方,但当我在代码中打印类似的内容时,它不会在控制台窗口中打印任何内容

Console.WriteLine("Connection Lost. Current Status Code " + Response.StatusCode);
如果您能在这个问题上分享您的一些智慧,我们将不胜感激。:)


我将尝试通过不修改太多原始代码来提供解决方案。我认为,当你熟悉使用BWs时,你会发现做事情的更好方法(包括逻辑)。因此,我将尝试解决您主要关心的问题

首先,你是对的,后台工作人员确实有一些你应该坚持的“设计”范例,可以保证线程安全

首先,BW的逻辑表面上很简单

1.)Dowwork,这是后台工作人员的肉/土豆。这是确保所有变量都已读取或保存、函数已执行等的好地方

2.)ReportProgress,在BackgroundWorker DoWork迭代结束时异步激发的函数。请稍后再谈

3.)WorkCompleted,后台工作人员在BW操作结束时执行功能的最终状态

现在常见的“问题”是在DoWORK中间执行UI或主线程代码。这里的调试/控制台WriteLine命令通常会崩溃或根本不执行。但是,拥有ReportProgress事件允许您在BackgroundWorker仍在运行时发送UI更新。这可能是为了显示命令而需要修改的代码部分

    BW.WorkerReportsProgress = true;
    BW.WorkerSupportsCancellation = true;
    BW.DoWork += new DoWorkEventHandler(BW_DoWork);
    BW.ProgressChanged += new ProgressChangedEventHandler(BW_ProgressChanged);
    BW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BW_WorkCompleted);

    private void BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine("Connection Lost. Current Status Code " + Response.StatusCode);
    }
既然您的后台工作程序已经正确配置,就必须非常小心地避免交叉线程。例如,我建议执行Try/Catch来处理对变量的跨线程访问实例(尽可能避免)。如果小心的话,这种情况确实会发生。或者,您可以使用Invoke命令的概念。不过,设计风格由你决定

        do
        {

        if (e.Cancel)
        {  
           return;
        }
        if (!reader.EOF)
        {
           ExtractDataFromStream(reader);
        }
        else
        {
            throw new Exception("EOF");
        }

        MONITOR.ReportProgress(0);

     } while (bwStreamData.IsBusy);
Report progress最初设计用于发送完成工作的整数“百分比”,但是,使用无限循环概念,您可以使用ReportProgress向用户/程序员传达其他有用的信息

需要注意的是,正如我最近了解到的,ReportProgress是非顺序的。这意味着它开始执行第二个调用,但BackgroundWorker不会暂停等待它完成

建议您希望在BackgroundWorker中包含哪些内容的逻辑:

CONTINUE = true;

while((CONTINUE)&&(!(reader.EOF)))
{
   if(StillConnected())
   {
      try
      {
          ExtractDataFromStream(reader);
      }
      catch (Exception ex)
      {
          CONTINUE = False;

          //Because we are on a separate thread, we can't update
          //the UI directly.  So we save the error message to a
          //global variable (string.)
          strErrorMessage = "Exception: " + ex.Message +
                            "\n\nStackTrace: " + ex.StackTrace;
      }
   }
   else
   {
      //To prevent infinite stuck loops, i.e. website goes down
      //try a counter
      if (RECONNECTCOUNT <= 1000)
      {
          Reconnect();
          RECONNECTCOUNT++;
      }
      else
      {
          CONTINUE = false;
          RECONNECTCOUNT = 0;
      }
   }

   //ProgressChanged Event can be used for reading data, saving data,
   //updating the UI, etc.
   BW.ReportProgress(0);
}
CONTINUE=true;
而((CONTINUE)和(!(reader.EOF)))
{
if(StillConnected())
{
尝试
{
从流中提取数据(读卡器);
}
捕获(例外情况除外)
{
CONTINUE=False;
//因为我们在一个单独的线程上,所以无法更新
//因此,我们将错误消息保存到
//全局变量(字符串)
strErrorMessage=“异常:”+ex.消息+
“\n\n堆栈跟踪:”+ex.StackTrace;
}
}
其他的
{
//为了防止无限的卡环,即网站关闭
//试试柜台

if(RECONNECTCOUNT这是RagingCain在我的原始代码块中替换do while循环的解决方案。感谢您的友好回答,RagingCain。请注意,我使用了原始代码的其余部分,包括响应变量

            bool mContinue = true;
            int mReconnectCount = 0;

            while ((mContinue) && (!(reader.EOF)))
            {
                if (Response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    try
                    {
                        ExtractDataFromStream(reader);
                    }
                    catch (Exception ex)
                    {
                        mContinue = false;

                        //Because we are on a separate thread, we can't update
                        //the UI directly.  So we save the error message to a
                        //global variable (string.)
                        string strErrorMessage = "Exception: " + ex.Message + "\n\nStackTrace: " + ex.StackTrace;
                        Console.WriteLine(strErrorMessage);

                    }
                }
                else
                {
                    //To prevent infinite stuck loops, i.e. website goes down
                    //try a counter
                    if (mReconnectCount <= 1000)
                    {
                        TryToReconnect();

                        mReconnectCount++;
                    }
                    else
                    {
                        mContinue = false;
                        mReconnectCount = 0;
                    }
                }

                //ProgressChanged Event can be used for reading data, saving data, etc.
                BW.ReportProgress(0);
            }

请尽量不要在你的问题标题中包含多余的标签。我已经编辑了你的帖子,从标题中删除了标签,并且还随意删除了问候语和感谢语,因为它们不被推荐。问候语尤其糟糕,因为当人们在主页上看到你的问题时,他们会看到第一段左右,你会浪费你的空间去做一些与问题无关的事情。谢谢你的回答。我现在正在研究你的答案。哈哈。一定要更新,我经常更新,最后我终于得到了我的咖啡:首先,这是一个很好的答案。非常感谢。刚刚发现报告的进度并没有达到应有的效果be.我将详细信息放在回答2.问候::)如果BackgroundWorker没有正确初始化,可能会发生这种情况。我注意到您缺少“System.ComponentModel”从上面的ProgressChangedEventHandler可以看出,您的代码中是否存在相同的错误?另外,根据您使用的Visual Studio版本,在配置“x86或x64”后,如果输出窗口未用于控制台或调试,则会出现错误。无论出于何种原因,切换回任何CPU都会修复它。我的解决方法是使用:MessageBox.Show(“Message”);这可以让您知道是否实际调用了代码。此外,请尝试使用断点。我确实缺少ProgressChangedEventHandler中的“System.ComponentModel”。在我添加“System.ComponentModel”之后,报告进度不会在我的控制台窗口上打印任何内容。::)我明白了。我想有
            bool mContinue = true;
            int mReconnectCount = 0;

            while ((mContinue) && (!(reader.EOF)))
            {
                if (Response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    try
                    {
                        ExtractDataFromStream(reader);
                    }
                    catch (Exception ex)
                    {
                        mContinue = false;

                        //Because we are on a separate thread, we can't update
                        //the UI directly.  So we save the error message to a
                        //global variable (string.)
                        string strErrorMessage = "Exception: " + ex.Message + "\n\nStackTrace: " + ex.StackTrace;
                        Console.WriteLine(strErrorMessage);

                    }
                }
                else
                {
                    //To prevent infinite stuck loops, i.e. website goes down
                    //try a counter
                    if (mReconnectCount <= 1000)
                    {
                        TryToReconnect();

                        mReconnectCount++;
                    }
                    else
                    {
                        mContinue = false;
                        mReconnectCount = 0;
                    }
                }

                //ProgressChanged Event can be used for reading data, saving data, etc.
                BW.ReportProgress(0);
            }
        BW = new System.ComponentModel.BackgroundWorker();

        BW.WorkerReportsProgress = true;
        BW.WorkerSupportsCancellation = true;


        BW.DoWork += new System.ComponentModel.DoWorkEventHandler(BW_DoWork);
        BW.ProgressChanged += new ProgressChangedEventHandler(BW_ProgressChanged);
        BW.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BW_RunWorkerCompleted);



    private static void BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine("Current Connection Status " + Response.StatusCode);
    }