"Stream not Writable" 在循环中使用 StreamWriter 时出错

"Stream not Writable" error when using StreamWriter in loop

我正在尝试用 C# 编写一个工具来帮助对一些网络问题进行质量检查,运行 遇到了问题。该程序应该每秒向服务器发送 JSON 格式的查询。

目前,它工作一次,但在第二次尝试发送查询时,我得到一个异常,因为

"Stream was not writable."

这是我的代码:

public partial class Form1 : Form
{
    Timer timer1;
    String query;
    String result;

    HttpWebRequest request;
    StreamWriter writeData;
    StreamReader readData;
    HttpWebResponse response;


    public Form1()
    {
        InitializeComponent();
        timer1 = new Timer();
        timer1.Tick += new EventHandler(timer1_Tick);
        timer1.Interval = 1000;
        File.Delete(AppDomain.CurrentDomain.BaseDirectory + "log.txt");
        logOutput.ReadOnly = true;
        request = (HttpWebRequest)WebRequest.Create("a URL goes here");
        request.ContentType = "application/json";
        request.Method = "POST";
        query = "{some json stuff goes here}";
    }

    private void startButton_Click(object sender, EventArgs e)
    {
        if (!timer1.Enabled)
        {
            timer1.Start();
            startButton.Text = "Stop";
        }
        else
        {
            timer1.Stop();
            startButton.Text = "Start";
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        writeData = new StreamWriter(request.GetRequestStream());
        writeData.Write(query);
        writeData.Flush();
        writeData.Close();

        response = (HttpWebResponse)request.GetResponse();
        readData = new StreamReader(response.GetResponseStream());

        result = readData.ReadToEnd();
        logOutput.Text = result;
        File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", result + "\r\n");
    }
}
}

有人知道我做错了什么吗?

所以我认为是 writeData.Write(query) 在扔东西? request.GetRequestStream() 应该只在请求实际发送之前是可写的,我相信当您调用 request.GetResponse() 时就已经完成了。所以它在第一次滴答时工作,但随后发送请求并且无法写入第二次。

您是否尝试多次发送请求?您需要重新初始化请求对象。

首先,使用全局变量停止。将 streamwriterstreamreaderhttpwebresponse 等移动到实际的 tick 方法中。

任何实现 IDisposable 的东西,大多数东西都是这样做的,应该是非常局部的变量,不会闲逛并包含在 using 子句中。

基本上,一旦您的方法完成,您的请求对象就会关闭。

像这样的东西会更好:

private void timer1_Tick( object sender, EventArgs e ) {

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("a URL goes here");

    request.ContentType = "application/json";
    request.Method = "POST";
    String query = "{some json stuff goes here}";
    String result = String.Empty;

    using ( StreamWriter writeData = new StreamWriter(request.GetRequestStream()) ) {
        writeData.Write(query);
        writeData.Flush();

        using ( HttpWebResponse response = (HttpWebResponse)request.GetResponse() ) {
            using ( StreamReader readData = new StreamReader(response.GetResponseStream()) ) {
                result = readData.ReadToEnd();
            }
        }
    }

    logOutput.Text = result;
    File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", result + "\r\n");
}

}

如果您不重新初始化请求,也会出现类似的问题。正如 ryachza 所提到的,我已将请求初始化推送到循环内并且它对我有用。

   foreach (String item in DATA)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
            request.Method = "POST";
            request.ContentType = "application/json";

            using (Stream webStream = request.GetRequestStream())
            using (StreamWriter requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII))
            {

                JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                Object routes_list =
                     json_serializer.DeserializeObject(item);
                requestWriter.Write(item);
            }


            WebResponse webResponse = request.GetResponse();
            using (Stream webStream = webResponse.GetResponseStream() ?? Stream.Null)
            using (StreamReader responseReader = new StreamReader(webStream))
            {
                response.Add(responseReader.ReadToEnd());

            }
        }