在循环中使用StreamWriter时出现“Stream not Writable”错误

时间:2015-08-21 19:08:18

标签: c# json streamwriter

我正在尝试用C#编写一个工具来帮助QA解决一些网络问题,并且遇到了问题。该程序应该每秒向服务器发送一个JSON格式的查询。

目前,它只运行一次,但在第二次尝试发送查询时,我得到一个例外,因为

  

“Stream不可写。”

这是我的代码:

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");
    }
}
}

任何人都知道我做错了什么?

3 个答案:

答案 0 :(得分:3)

首先,使用全局变量停止。将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");
}

}

答案 1 :(得分:0)

所以我认为它是writeData.Write(query)投掷的? request.GetRequestStream()只应在实际发送请求之前可写,我相信当您致电request.GetResponse()时就会这样做。所以它适用于第一个滴答,但随后发送请求并且不能再次写入。

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

答案 2 :(得分:0)

如果不重新初始化请求,则会导致类似问题。如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());

            }
        }