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