"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()
时就已经完成了。所以它在第一次滴答时工作,但随后发送请求并且无法写入第二次。
您是否尝试多次发送请求?您需要重新初始化请求对象。
首先,使用全局变量停止。将 streamwriter
、streamreader
、httpwebresponse
等移动到实际的 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());
}
}
我正在尝试用 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()
时就已经完成了。所以它在第一次滴答时工作,但随后发送请求并且无法写入第二次。
您是否尝试多次发送请求?您需要重新初始化请求对象。
首先,使用全局变量停止。将 streamwriter
、streamreader
、httpwebresponse
等移动到实际的 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());
}
}