C# 例外情况:;请求被中止:连接意外关闭;调用同一对象的两个方法时

C# 例外情况:;请求被中止:连接意外关闭;调用同一对象的两个方法时,c#,httpwebrequest,cisco,C#,Httpwebrequest,Cisco,我有一个很多人都经历过的问题,但所有在线可用的解决方案都是针对他们的场景的。我已经尝试了可用的建议,但仍然没有运气我尝试的是: 1.) req.KeepAlive = false; 2.) req.ProtocolVersion = HttpVersion.Version10; (this solved a different exception that I was getting) 我有两种方法将XML字符串传递到服务器并获取响应这两种方法是: public string userDevi

我有一个很多人都经历过的问题,但所有在线可用的解决方案都是针对他们的场景的。我已经尝试了可用的建议,但仍然没有运气我尝试的是:

1.) req.KeepAlive = false;
2.) req.ProtocolVersion = HttpVersion.Version10; (this solved a different exception that I was getting)
我有两种方法将XML字符串传递到服务器并获取响应这两种方法是:

public string userDeviceQuery(string userID)
    {
        string query = "xml=<query>";
        query += "<appInfo>";
        query += "<appID>" + appID + "</appID>";
        query += "<appCertificate>" + appCertificate + "</appCertificate>";
        query += "</appInfo>";
        query += "<userDevicesQuery>";
        query += "<userID>";
        query += userID;
        query += "</userID>";
        query += "</userDevicesQuery>";
        query += "</query>";

        using (Stream str = req.GetRequestStream())
        {
            str.Write(System.Text.Encoding.ASCII.GetBytes(query), 0, query.Length);
        }

        WebResponse res = req.GetResponse();

        string stringResponse;
        using (StreamReader reader = new StreamReader(res.GetResponseStream()))
        {
            stringResponse = reader.ReadToEnd();
        }

        string result = parseDeviceQueryRes(stringResponse);
        return result;
    }
publicstringuserdevicequery(stringuserid)
{
string query=“xml=”;
查询+=“”;
查询+=“”+appID+“”;
查询+=“”+appCertificate+“”;
查询+=“”;
查询+=“”;
查询+=“”;
query+=userID;
查询+=“”;
查询+=“”;
查询+=“”;
使用(Stream str=req.GetRequestStream())
{
str.Write(System.Text.Encoding.ASCII.GetBytes(query),0,query.Length);
}
WebResponse res=req.GetResponse();
字符串响应;
使用(StreamReader=newstreamreader(res.GetResponseStream()))
{
stringResponse=reader.ReadToEnd();
}
字符串结果=ParseDeviceQueryResponse(stringResponse);
返回结果;
}

public void logoutOfEM(字符串deviceName)
{
string lgRequest=“xml=”;
lgRequest+=“”;
lgRequest+=“”+appID+“”;
lgRequest+=“”+appCertificate+“”;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=deviceName;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=“”;
使用(Stream str=req.GetRequestStream())
{
str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest),0,lgRequest.Length);
}
WebResponse res=req.GetResponse();
使用(StreamReader=newstreamreader(res.GetResponseStream()))
{
stringResponse=reader.ReadToEnd();
}
string stringResponse=reader.ReadToEnd();
}
它们都属于一个叫做EMAPI的类。我可以单独使用这两种方法,但如果尝试将它们与表示EMAPI的同一对象背靠背地使用,则会出现上述异常。我不确定是什么原因导致连接关闭,我希望能够保持它打开,并尽可能使用反构造函数关闭它

对于那些好奇的人来说,这段代码涉及Cisco Extension Mobility API,第一种方法查询服务器以获取您登录的设备,第二种方法将用户从该设备注销


谢谢你的帮助。

首先,我会在我所有的IDisPobles中使用“using”关键字。第二,看起来您正在打开StreamReaders

编辑

回答您关于使用关键字的评论

与此相反:

Stream str = req.GetRequestStream();
str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
str.Close();
这样写:

using(Stream str = req.GetRequestStream())
{
    str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
}
using关键字将自动为您处理所有IDisplosable任务

我只是注意到了一些你的代码和为什么我认为你没有关闭。您正在呼叫close,然后试图准备好线路。这是一个很好的例子,说明了为什么要养成使用“using”关键字的习惯

StreamReader reader = new StreamReader(res.GetResponseStream());
reader.Close(); //Calling CLOSE before trying to use the reader
string stringResponse = reader.ReadToEnd();
另一次编辑

public void logoutOfEM(string deviceName)
    {
        string lgRequest = "xml=<request>";
               lgRequest += "<appInfo>";
               lgRequest += "<appID>" + appID + "</appID>";
               lgRequest += "<appCertificate>" + appCertificate + "</appCertificate>";
               lgRequest += "</appInfo>";
               lgRequest += "<logout>";
               lgRequest += "<deviceName>";
               lgRequest += deviceName;
               lgRequest += "</deviceName>";
               lgRequest += "</logout>";
               lgRequest += "</request>";
     using (Stream str = req.GetRequestStream())
    {
        str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
    }

    WebResponse res = req.GetResponse();

    var response = string.Empty;
    using(StreamReader reader = new StreamReader(res.GetResponseStream()))
    {
        response = reader.ReadToEnd();
    }


}
public void logoutOfEM(字符串deviceName)
{
string lgRequest=“xml=”;
lgRequest+=“”;
lgRequest+=“”+appID+“”;
lgRequest+=“”+appCertificate+“”;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=deviceName;
lgRequest+=“”;
lgRequest+=“”;
lgRequest+=“”;
使用(Stream str=req.GetRequestStream())
{
str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest),0,lgRequest.Length);
}
WebResponse res=req.GetResponse();
var response=string.Empty;
使用(StreamReader=newstreamreader(res.GetResponseStream()))
{
response=reader.ReadToEnd();
}
}

对每个方法使用不同的HttpWebRequest。您不应该为不同的请求重用HttpWebRequest对象。检查此项:。在内部,如果可能,.NET可以决定重用与同一服务器的连接,但服务器可以在每次请求后决定关闭连接,即使您指定req.KeepAlive=true


另外,请确保在方法中处置/关闭WebResponse对象。

在一个不相关的注释中,我将使用stringbuilder在构造巨大+字符串时提高效率。请详细说明,为什么stringbuilder在连接字符串时更好?您是否检查了第一次调用后的连接状态。可能是远程服务器关闭了连接。哦,哇,我的代码中有15个使用字符串的查询,我将修复它们。这可以解决我所经历的缓慢。塔恩克斯!!我确实关闭了所有StreamReader,但这并没有帮助我不确定您所指的“首先在我所有的IDisPobles周围使用'using'关键字”是什么,这说明了为什么我们应该这样做,但它仍然没有解决问题,我已经更新了问题中的代码在您编辑的问题中,您仍然在呼叫reader.close()在方法LOGOUTOFEM中关闭读取器后尝试使用读取器在两种方法中都是不同的读取器,我正在创建一个读取器并在两种方法中关闭读取器是的,但您仍然不理解。在方法logoutOfEM中执行ReadToEnd()之前,您正在调用close。我在编辑中更正了它。我只将它设置为false,只是为了尝试来自不同线程的建议,我同时尝试了“true”和“false”。我更新了我的答案,您不应该对不同的请求重复使用HttpWebRequest。谢谢,这才是问题所在。
public void logoutOfEM(string deviceName)
    {
        string lgRequest = "xml=<request>";
               lgRequest += "<appInfo>";
               lgRequest += "<appID>" + appID + "</appID>";
               lgRequest += "<appCertificate>" + appCertificate + "</appCertificate>";
               lgRequest += "</appInfo>";
               lgRequest += "<logout>";
               lgRequest += "<deviceName>";
               lgRequest += deviceName;
               lgRequest += "</deviceName>";
               lgRequest += "</logout>";
               lgRequest += "</request>";
     using (Stream str = req.GetRequestStream())
    {
        str.Write(System.Text.Encoding.ASCII.GetBytes(lgRequest), 0, lgRequest.Length);
    }

    WebResponse res = req.GetResponse();

    var response = string.Empty;
    using(StreamReader reader = new StreamReader(res.GetResponseStream()))
    {
        response = reader.ReadToEnd();
    }


}