C# Winform递归循环-方法被反复调用
请随意创建windows窗体应用程序。要再现错误,请禁用网络连接并运行代码。它每1秒尝试重新连接一次。在4-5次尝试后,启用网络连接,并在调试模式下,您将注意到,即使获取产品,Reconnect()方法也会被调用4-5次。获取产品后,为什么它会一次又一次地调用Reconnect()方法C# Winform递归循环-方法被反复调用,c#,winforms,C#,Winforms,请随意创建windows窗体应用程序。要再现错误,请禁用网络连接并运行代码。它每1秒尝试重新连接一次。在4-5次尝试后,启用网络连接,并在调试模式下,您将注意到,即使获取产品,Reconnect()方法也会被调用4-5次。获取产品后,为什么它会一次又一次地调用Reconnect()方法 string apiUrl = "https://api.gdax.com/products"; string json; private void Form1_
string apiUrl = "https://api.gdax.com/products";
string json;
private void Form1_Load(object sender, EventArgs e)
{
try
{
if (FillProducts()) // product need first
{
}
}
catch (WebException ex)
{
ReconnectOnError(ex);
}
}
private bool FillProducts()
{
bool isDone = false;
try
{
json = GetGDXJSONData(apiUrl);
JsonSerializer serializer = new JsonSerializer();
DataTable dt = (System.Data.DataTable)Newtonsoft.Json.JsonConvert.DeserializeObject(json, (typeof(System.Data.DataTable)));
count = dt.Rows.Count;
if (count > 0)
isDone = true;
}
catch (Exception ex)
{
isDone = false;
ReconnectOnError(ex);
}
return isDone;
}
int count = 0;
private void ReconnectOnError(Exception errorMessage)
{
try
{
Thread.Sleep(1000);
if (count < 1)
{
FillProducts(); // it comes on this point again and again even the count is greater than 1
Reconnect();
}
else
{
Reconnect();
}
}
catch (WebException ex)
{
ReconnectOnError(ex);
}
}
private void Reconnect()
{
// why this is called the number of times the attempt was made to fill the products?
}
private string GetGDXJSONData(string apiUrl)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl);
request.Method = "GET";
request.ContentType = "application/json";
request.UserAgent = "gdax-node-client";
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return responseString;
}
}
这是因为如果没有网络连接,那么调用API url将无法连接,并且在
catch
块中,您正试图重新连接
catch (Exception ex)
{
isDone = false;
ReconnectOnError(ex);
}
没有internet连接时。计数变量始终为零。这里有一个意外循环: 如果
FillProducts
失败,它将调用自己
重新连接
,整个堆栈将展开
private bool FillProducts()
{
bool isDone = false;
try
{
/* ... Fails if no connection ... */
}
catch (Exception ex)
{
isDone = false;
ReconnectOnError(ex); // ==> BLOCKS !!
}
return isDone;
}
int count = 0;
private void ReconnectOnError(Exception errorMessage)
{
try
{
Thread.Sleep(1000);
if (count < 1)
{
FillProducts(); // <== Will result in another call to this method. Returns on 1st Succeeding call to FillProducts.
Reconnect(); // <== Will be called as soon as FillProducts returns.
}
else
{
Reconnect();
}
}
catch (WebException ex)
{
ReconnectOnError(ex);
}
}
需要考虑的其他几点:
这是由于
中的else部分,如果(count<0)
你再次调用它,我必须这样做。。不过,它不会出现在这条线上。如果您运行代码,您将看到它调用FillProducts();重新连接();一次又一次,即当没有Internet时,它第一次尝试重新连接的次数您有一个间接递归调用-FillProducts()
调用重新连接错误(ex)代码>如果出现调用FillProducts()
的异常。请运行代码并在不使用internet的情况下进行调试,然后在尝试4-5次重新连接后启动internet。请不要停止我正在尝试重新连接的应用程序,但我的问题是,一旦internet恢复,为什么它仍然调用4-5次reconnect()方法?请单击“在此处输入图像描述”链接
private bool FillProducts()
{
bool isDone = false;
try
{
/* ... Fails if no connection ... */
}
catch (Exception ex)
{
isDone = false;
ReconnectOnError(ex); // ==> BLOCKS !!
}
return isDone;
}
int count = 0;
private void ReconnectOnError(Exception errorMessage)
{
try
{
Thread.Sleep(1000);
if (count < 1)
{
FillProducts(); // <== Will result in another call to this method. Returns on 1st Succeeding call to FillProducts.
Reconnect(); // <== Will be called as soon as FillProducts returns.
}
else
{
Reconnect();
}
}
catch (WebException ex)
{
ReconnectOnError(ex);
}
}
private bool FillProducts()
{
// To prevent waiting forever ...
int retryCount = 10;
bool isDone = false;
while ( !isDone && (retryCount-- > 0) )
{
try
{
/* ... Fails if no connection ... */
// OnSuccess=>
isDone = true; // will break the loop.
}
catch (Exception ex) // You should actually catch a more specific Exception here
// ... but that's a different question.
{
isDone = false;
// Just omit this! >>> ReconnectOnError(ex); // ==> BLOCKS !!
// If you want, you can add a little delay here ...
Thread.Sleep(1000);
// From your code, I guess this has to be called on failure ...
Reconnect();
}
}
return isDone;
}