为什么此代码在到达 StreamReader 的第一个 ReadLine 时挂起?

2024-01-07

我在第一个参数中将一个大文件传递给下面的 SendXMLFile(),但由于它导致手持设备“挂起”/“冻结”,我暂时硬编码了一个小得多的文件(3 KB,而不是 1121 KB)供测试用。

该文件确实存在(与 .exe/.dll 位于同一文件夹中),如以下代码所示:

// test with smaller file:
fileName = "DSD_v6666_3_20140310140737916.xml";
MessageBox.Show("Made it before file.Open");
using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew)) 
{
    fileTest.Write(info, 0, info.Length);
    fileTest.Flush();
}
if (!File.Exists(fileName))
{
    MessageBox.Show(String.Format("{0} does not seem to exist", fileName));
} 
else
{
    MessageBox.Show(String.Format("{0} DOES seem to exist", fileName));
}

string justFileName = Path.GetFileNameWithoutExtension(fileName);
String uri = String.Format(@"http://SHANNON2:21609/api/inventory/sendXML/gus/woodrow/{0}", justFileName).Trim();
SendXMLFile(fileName, uri, 500);

以下是随后调用的代码,尝试发送文件:

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    // TODO: Remove after testing
    String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout);
    MessageBox.Show(s);
    // </ TODO: Remove after testing

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

    //request.KeepAlive = false; // should this be true? <== commented out as a test, but no diff in behavior
    request.ProtocolVersion = HttpVersion.Version10;
    request.ContentType = "application/xml";
    request.Method = "POST";

    StringBuilder sb = new StringBuilder();
    // TODO: Remove after testing
    MessageBox.Show("Made it to just before the StreamReader using");
    using (StreamReader sr = new StreamReader(xmlFilepath))
    {
        // TODO: Remove after testing
        MessageBox.Show("Made it just inside the StreamReader using"); // <= This is the last point reached 
        String line;
        while ((line = sr.ReadLine()) != null)
        {
            // TODO: Remove after testing
            MessageBox.Show(string.Format("line == {0}", line));
            sb.Append("\r\n");
        }
        . . .

当我运行这个时,我看到:

"Made it before file.Open"
"DSD_v6666_3_20140310140737916.xml DOES seem to exist"
[The xmlFilepath, uri, and timout vals expected]
"Made it to just before the StreamReader using"
"Made it just inside the StreamReader using"

——但不是“线==...“消息 - 它挂起,我必须热启动设备才能将其从电子困境中恢复。

StreamReader 代码是否存在潜在问题,或者......???

UPDATE

我不知道这是数据中的问题,还是我必须在代码中做出的更改才能使其在紧凑框架中工作。我有非常相似的代码,可以在 Winforms 应用程序中使用:

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

    request.KeepAlive = false;
    request.ProtocolVersion = HttpVersion.Version10;
    request.ContentType = "application/xml";
    request.Method = "POST";

    StringBuilder sb = new StringBuilder();
    using (StreamReader sr = new StreamReader(xmlFilepath))
    {
        String line;
        while ((line = sr.ReadLine()) != null)
        {
            sb.AppendLine(line);
        }
        byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());

        if (timeout < 0)
        {
            request.ReadWriteTimeout = timeout;
            request.Timeout = timeout;
        }

        request.ContentLength = postBytes.Length;

        try
        {
            Stream requestStream = request.GetRequestStream();

            requestStream.Write(postBytes, 0, postBytes.Length);
            requestStream.Close();

            //using (var response = (HttpWebResponse)request.GetResponse())
            //{
            //    return response.ToString();
            //}
            // alternate way, safe for older versions of .NET
            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse(); 
            }
            finally
            {
                IDisposable disposableResponse = response as IDisposable;
                if (disposableResponse != null) disposableResponse.Dispose();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            request.Abort();
            return string.Empty;
        }
    }
}

---像这样调用,传递相同的文件作为测试用例:

private void button20_Click(object sender, EventArgs e)
{
    // Change the file name before each test
    String fullFilePath = @"C:\HoldingTank\DSD_v6666_3_20140310140737916.xml";
    string justFileName = Path.GetFileNameWithoutExtension(fullFilePath);
    String uri = String.Format(@"http://localhost:21608/api/inventory/sendXML/su/su/{0}", justFileName);
    SendXMLFile(fullFilePath, uri, 500);
}

UPDATE 2

我更改了代码以使用 XMLTextReader,现在我又回到了之前遇到的错误,即“(400) Bad Request”,该错误的大部分细节都记录在案here https://stackoverflow.com/questions/25516012/why-would-i-get-the-remote-server-returned-an-error-400-bad-request-with-t.

这是新代码,以及我现在看到的:

public static bool WriteIt2( 字符串文件名, 字符串数据, long fsize ) { 布尔 retVal = false; int bytRd = 0; // 如果使用这个,改变它的名字 字符串 the_Msg = "";

if (File.Exists(fileName))
{
    File.Delete(fileName);
}

Byte[] info = Encoding.UTF8.GetBytes(data);
// Testing with this relatively small file for now
fileName = "DSD_v6666_3_20140310140737916.xml";
MessageBox.Show("Made it before file.Open");
using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew)) 
{
    fileTest.Write(info, 0, info.Length);
    fileTest.Flush();
}
if (!File.Exists(fileName))
{
    MessageBox.Show(String.Format("{0} does not seem to exist", fileName));
} // I have never seen the msg above, but always saw the one below, so commented it out
else //<= always exists, so unnecessary
{
    MessageBox.Show(String.Format("{0} DOES seem to exist", fileName));
}

string justFileName = Path.GetFileNameWithoutExtension(fileName);
String uri = String.Format(@"http://SHANNON2:21609/api/inventory/sendXML/su/su/{0}", justFileName).Trim();

SendXMLFile(fileName, uri, 500);

现在这里是实际执行读取、写入和发送(或尝试执行)的代码:

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout);
    MessageBox.Show(s);
    // </ TODO: Remove after testing

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

    request.ProtocolVersion = HttpVersion.Version10;
    request.ContentType = "application/xml";
    request.Method = "POST";

    StringBuilder sb = new StringBuilder();
    MessageBox.Show("Made it to just before the StreamReader using");

    StreamReader sr = new StreamReader(xmlFilepath);
    MessageBox.Show("Made it past the StreamReader being constructed");
    XmlTextReader reader = null;    
    reader = new XmlTextReader(sr);
    while (reader.Read()) 
    {
        switch (reader.NodeType) 
        {
            case XmlNodeType.Element: // The node is an Element.
                sb.Append("<" + reader.Name);
            while (reader.MoveToNextAttribute()) // Read attributes.
                sb.Append(" " + reader.Name + "='" + reader.Value + "'");
                sb.Append(">");
                sb.Append(">");
                break;
            case XmlNodeType.Text: //Display the text in each element.
                sb.Append (reader.Value);
                break;
            case XmlNodeType. EndElement: //Display end of element.
                sb.Append("</" + reader.Name);
                sb.Append(">");
                break;
        }
    }
    // TODO: Remove after testing
    MessageBox.Show("Made it past the while loop");
    MessageBox.Show(String.Format("sb first line is {0}", sb[0].ToString()));
    MessageBox.Show(String.Format("sb tenth line is {0}", sb[9].ToString()));
    byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());

    if (timeout < 0)
    {
        request.Timeout = timeout;
    }

    request.ContentLength = postBytes.Length;

    try
    {
        Stream requestStream = request.GetRequestStream();

        requestStream.Write(postBytes, 0, postBytes.Length);
        requestStream.Close();

        // This code for older versions of .NET from ctacke:
        HttpWebResponse response = null;
        try
        {
            response = (HttpWebResponse)request.GetResponse();
            return response.ToString();
        }
        finally
        {
            IDisposable disposableResponse = response as IDisposable;
            if (disposableResponse != null) disposableResponse.Dispose();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        request.Abort();
        return string.Empty;
    }
}

当它运行时我现在看到的是:

0) "Made it before file.Open"
1) "DSD_v6666_3_20140310140737916.xml DOES seem to exist"
2) [ the xmlFilePath and other args - they are what is expected ]
3) "Made it to just before the StreamReader using"
4) "Made it past the StreamReader being constructed
5) "Made it past the while loop
6) "sb first line is "<"
7) "sb tenth line is ">"
8) "The remote server returned an error (400) Bad Request"

所以至少它不再挂起,但我又想知道为什么服务器认为这是一个错误的请求。


我认为你应该回到基础:

public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
    using (var client = new WebClient())
    {                
        client.Headers.Add("Content-Type", "application/xml");                
        byte[] response = client.UploadFile(uri, "POST", xmlFilepath);
        return Encoding.ASCII.GetString(response);
    }
}

并查看什么有效以及服务器如何看待您的文件。

当你确实需要超时时,请参阅这个答案 https://stackoverflow.com/a/3052637/60761

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么此代码在到达 StreamReader 的第一个 ReadLine 时挂起? 的相关文章

  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 使用可变参数包类型扩展的 C++ 函数调用者包装器

    我绑定了一些 API 并且绑定了一些函数签名 如下所示 static bool WrapperFunction JSContext cx unsigned argc JS Value vp 我尝试将对象和函数包装在 SpiderMonkey
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 如何在 Qt 应用程序中通过终端命令运行分离的应用程序?

    我想使用命令 cd opencv opencv 3 0 0 alpha samples cpp cpp example facedetect lena jpg 在 Qt 应用程序中按钮的 clicked 方法上运行 OpenCV 示例代码
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • 堆栈是向上增长还是向下增长?

    我在 C 中有这段代码 int q 10 int s 5 int a 3 printf Address of a d n int a printf Address of a 1 d n int a 1 printf Address of a
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有

随机推荐