C#でGUIを作成して、WEBサーバー上のPHPで作った簡易APIにPOSTしてサーバー側に
データを溜め込みそれをC#のGUI側で随時表示という、いわばGUIのチャットをつくっています。まず、GUIをつくりGUI上のフォームからテキストを入力してサーバー側のPHPへPOSTしログとしてためることはできましたが、どうもGUI側で連続ポスト・・・大体い1~2秒に一度ポストすると、三度目のポストでGUIがフリーズしています。ただしアプリが落ちるわけでなく、POST完了にずいぶん時間がかかっているらしく一分ぐらいするとPOSTが完了してフリーズも直ります。このパターンが続きます。
つまり、3の倍数の回数目のPOSTのみフリーズするのです。なんとか、これを解消して
問題なく連続POSTができるようにしたいのです。お力添え願います。ソースは以下になります。
using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Web;
using System.Net;
using System.Text;
public class MainClass{
public static void Main(string [] args){
NewForm formObj = new NewForm(500,500);
formObj.SetTitle("チャットアプリサンプル");
Application.EnableVisualStyles();
Application.Run(formObj);
}
}
public class NewForm : Form{
//Formに付加するコントロールオブジェクト
public Label labelObj =new Label();
public Button buttonObj =new Button();
public TextBox boxObj =new TextBox();
public TextBox responseBox =new TextBox();
public UserRequest user;
public NewForm( int localWidth,int localHeight){
this.Width = localWidth;
this.Height = localHeight;
this.boxObj.Width = localWidth/2;
this.boxObj.Height = localHeight/2;
this.boxObj.Multiline =true;
this.boxObj.Location = new Point(50,200);
this.responseBox.Width =300;
this.responseBox.Height =150;
this.responseBox.Multiline =true;
this.Controls.Add(this.responseBox);
this.buttonObj.Text ="サーバーへ送信";
this.buttonObj.Width =150;
this.buttonObj.Height =50;
this.buttonObj.Location =new Point(350,10);
this.buttonObj.Click += new EventHandler(this.ClickMethod);
this.Controls.Add(this.boxObj);
this.Controls.Add(this.buttonObj);
this.user = new UserRequest("http://localhost/csharp.php");
}
public void SetTitle(String titleText){
this.Text = titleText;
}
public void ClickMethod(Object sender , EventArgs e){
this.user.SetUrlPath("http://localhost/csharp.php");
this.user.SetPostData(this.boxObj.Text,"POST");
this.user.SendData();
this.boxObj.Text = "";
this.user.DeleteStream();
}
}
//通信用クラスの定義
public class UserRequest{
//HTTPリクエストオブジェクト
private HttpWebRequest http;
//通信先のURL
private string path = "";
//通信先URLへとPOSTするpostdata
private string postData ="";
//通信のメソッドタイプ
private string method ="POST";
//contenttypeの指定
private string ct = "application/x-www-form-urlencoded";
//送信データの文字列のurlエンコードを行う。
private Encoding encode = Encoding.GetEncoding("UTF-8");
//postデータをバイト型配列に
private byte [] postDataBytes;
//実際にpostデータを送受信するためのStreamを用意しておく
private Stream reqStream;
private Stream resStream;
/*
この辺は、迷っています。独自クラスのUserRequestというクラスのコンストラクタで
HttpWebRequestのオブジェクトをつくってやるか
それとも、オブジェクト作成のためだけのメソッドを定義してやるか・・・。
public UserRequest(string httpPath){
//this.path = httpPath;
//httpオブジェクトの作成
//this.http =(HttpWebRequest) WebRequest .Create(this.path);
}
public void SetUrlPath (string setUrlpathData){
this.path = setUrlpathData;
this.http =(HttpWebRequest) WebRequest .Create(this.path);
}
*/
//postDataのセット
public void SetPostData (string postDataParam,string methodType){
//ポストデータをUrlエンコードしアスキー文字にまとめる。
this.postData = "messageData=" + HttpUtility.UrlEncode(postDataParam,this.encode);
//postDataをバイト配列型に格納する。
this.postDataBytes = Encoding.ASCII.GetBytes(this.postData);
this.method = methodType;
//HTTPオブジェクトにそれぞれの値を設定する。
this.http.ContentType = this.ct;
this.http.Method = this.method;
this.http.ContentLength = this.postDataBytes.Length;
}
public void SendData (){
try{
using(this.reqStream = http.GetRequestStream()){
this.reqStream.Write(this.postDataBytes,0,this.postDataBytes.Length);
this.reqStream.Close();
}
}catch(Exception e){
MessageBox.Show(e.ToString());
}
}
public void DeleteStream(){
this.http = null;
this.reqStream = null;
}
}
PHPとかjsは仕事でつかっているのですが
C#見たく、完全なOOPを扱うのは初めてなので
うまいユーザー定義のクラスではないかもしれません。
No.2ベストアンサー
- 回答日時:
UIスレッドで時間のかかる処理を行うことをやってはいけません。
時間がかかるならば非同期処理を行う必要があります。
・.NET 4.5~の場合
async/awaitを使うのが簡単でしょう。
コンパイラが頑張ってステートマシンを作ってくれて,処理のほとんどをUIスレッドで処理を実行してくれます。
# かつ,Networkアクセスは非同期
http://msdn.microsoft.com/ja-jp/library/hh156513
http://msdn.microsoft.com/ja-jp/library/system.n …
・.NET 2.0~の場合
本来なら,以下の.NET 1.0~の場合と同じ方法がよいのですが,
UI弄るのが面倒なので,BackgroundWorkerを使うのが簡単です。
# .NET 4.0だとRxという解もあるけれども省略。
http://msdn.microsoft.com/ja-jp/library/system.c …
・.NET 1.0~の場合
WebRequest.BeginGetResponseとWebRequest.EndGetResponseを使ったパターンを使うことになります。
UI弄るのは面倒ですが,Control.Invokeを使ってUIスレッドで実行するように書く必要があります。
http://msdn.microsoft.com/ja-jp/library/system.n …
http://msdn.microsoft.com/ja-jp/library/zyzhdc6b
GUIとは別に、WEBサーバー側へ
データをPOSTする処理だけThreadクラスを用いて別スレッドとして処理しました。
>UI弄るのは面倒ですが,Control.Invokeを使ってUIスレッドで実行するように書く必要があります。
というのは、メインスレッド上のフォーム要素に別スレッドから何かしらメインスレッド上のフォームにアクセスする場合に用いれるものですね。
面倒なときは、別スレッドで実行するデリゲートの中身をまるっとControls.Invoke()で
ラップしてやるといいんですね。
本来はInvokeRequiredで
ちゃんと条件わけしてやるのがよいのでしょうけど「・・・。
No.1
- 回答日時:
Webサーバー等にリクエストを出した時には,
たいていレスポンスが返ってくるまで,時間がかかってくるものだと思うから
ある程度のフリーズは,やむを得ないと思いますし,
高速にリクエストを出し続けたら,サーバー側が耐えられなくなるんじゃないですかね.
とにかく連続して出したいなら,
マルチスレッドにするか,
もしかしたら,
HttpWebRequestのProxy プロパティをnullに設定すると,
多少改善するかも.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
- VPN 何これ 1 2022/04/19 01:32
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- 英語 「this is the/my first time~」の文法上の制約について 1 2023/04/06 09:48
- 英語 この英語の問題が分かりません 3 2023/04/22 20:19
- 英語 Statistically significant differences (p < 0.05), 5 2022/05/03 01:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
[C#.net]スレッド化された別フ...
-
Javaでパラパラアニメを作成す...
-
大量のデータを読み込んで表示...
-
数独の問題作成
-
ボタンのイベントで異なるウィ...
-
【java】座標の値をテキストフ...
-
Thread.sleepのInterruptedExce...
-
Junitテストでvoid戻り値メッソ...
-
GetDIBits関数の使い方について
-
C#で、あるクラスのメンバーす...
-
javaアプレット repaintのタイ...
-
C# DataGridView列カスタマイズ
-
【javaアプレット】スクロール...
-
C# 半角カナの文字化けについて
-
ペイントソフトを作っているの...
-
二分探索木の要素の数を数える...
-
Processingでマウスクリックで...
-
struts2のchainで値の受け渡し...
-
C# タスク非表示でタイトルバー...
-
JWindow、JFrameでモーダル化の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
大量のデータを読み込んで表示...
-
ボタンの複数割り当てについて
-
C#で、あるクラスのメンバーす...
-
Junitテストでvoid戻り値メッソ...
-
C#でのWNetAddConnection3の使...
-
C# 矢印キーの取得
-
Thread.sleepのInterruptedExce...
-
unityでのC++エラーの原因がわ...
-
C#で別のFormへ複数の値を返そ...
-
C# visibleプロパティをfalseに...
-
エンターキーを押すとOKボタン...
-
Processingでマウスクリックで...
-
[C#.net]スレッド化された別フ...
-
C#でキーイベントが発生しない...
-
C# DataGridView列カスタマイズ
-
【C#】ソースコードをファイル...
-
LVM_SETITEMSTATEでListViewの...
-
GetDIBits関数の使い方について
-
未割り当てのローカル変数
-
C# MouseHoverを何度も呼ぶには
おすすめ情報