C#, C♯, C#相談室 Part52at TECH
C#, C♯, C#相談室 Part52 - 暇つぶし2ch846:デフォルトの名無しさん
09/06/09 16:32:02
tcpClient tcp;
public NetworkStream ns;
public Queue<Byte> ReadQueue = new Queue<Byte>();
Byte[] ReadData = new byte[512];

public Test(string hostname, int port)
{
tcp = new TcpClient(hostname, port);
ns = tcp.GetStream();
ns.BeginRead(ReadData, 0, ReadData.Length, CBRead, ns);
}

private void CBRead(IAsyncResult ar)
{
NetworkStream ns = (NetworkStream)ar.AsyncState;
Int32 cnt = ns.EndRead(ar);
for (int i = 0; i < cnt; i++)
{
ReadQueue.Enqueue(ReadData[i]);
}
ns.BeginRead(ReadData, 0, ReadData.Length, CBRead, ns);
}


Queueを使ってやりたいことは大体こんな感じです。
延々とバックグラウンドで受信しているイメージです。
パフォーマンス的にどうなのかなあ、自前リングバッファの方がいいのかなあと言う疑問でした。

ちょっと質問からずれるのですが、連続してストリームを処理する場合のBeginReadの
使い方ってこれであってます?

847:デフォルトの名無しさん
09/06/09 16:34:52
Mainが無かったです

static void Main(string[] args)
{
test("192.168.1.100", 10001);
while (true)
{
while (wl.ReadQueue.Count > 0)
{
Byte b = wl.ReadQueue.Dequeue();
Console.Write(b.ToString("X2"));
}
}
}


848:デフォルトの名無しさん
09/06/09 16:47:38
もうQueueなんて使わないでMemoryStreamに流し続ければいいんでない?
そしてCBRead()の最後がキモい
だれも止められないじゃん

849:デフォルトの名無しさん
09/06/09 16:55:12
>>848
どうしてもバッファから取り出した分を詰める作業が必要なのでMemoryStreamはちょっと。

最後キモイですか。
我ながらこりゃあいいやと思ったんですが、どうしましょうか。

850:デフォルトの名無しさん
09/06/09 17:08:55
んーいまいちQueueの用途がわからない
もしかして>>846は肝心の”取り出した分を詰める作業”が書かれていない?

しかも,そもそもTCPなんだからByte型のデータを自前でバッファする必要性をあまり感じないんだが.
むしろQueueに突っ込むのは,データストリームから取り出した使えるデータの方がヨサゲ

851:デフォルトの名無しさん
09/06/09 17:13:56
だよね
少なくともバイト数が分かる仕様ぽいから、
受信スレッドがひたすらまとまり単位でバイト配列に取り出してバイト配列をキューに追加
処理スレッドがキューからひたすら取り出して処理すればいいような気がする。
ああ、スレッド間の同期はちゃんとやってね。


852:デフォルトの名無しさん
09/06/09 17:15:44
その場合は簡単なブロッキングキューを作ればよりシンプルになるかも。

853:デフォルトの名無しさん
09/06/09 19:30:09
>>810
亀だけどサンクス
思ったより知りたいことが書いてあったので為になった!

854:デフォルトの名無しさん
09/06/09 20:41:04
public static object GetMyObject() {
 AssemblyName asmName = new AssemblyName("myAsm");
 AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
 ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("myModule");
 TypeBuilder typeBuilder = modBuilder.DefineType("myClass", TypeAttributes.Public, typeof(object));
 typeBuilder.DefineField("x", typeof(int), FieldAttributes.Public);
 typeBuilder.DefineField("y", typeof(int), FieldAttributes.Public);
 Type mytype = typeBuilder.CreateType();
 return Activator.CreateInstance(mytype);
}

という動的クラスのインスタンスを返す関数を作って

propertyGrid.SelectedObject = GetMyObject();

とやってみましたが、プロパティグリッドにはなにも表示されません。
GetMyObject() の戻り値をみてみたところ、クラス名 myClass で
メンバ x, y も存在し、意図したとおりのクラスとインスタンスが
生成されているように見えるのですが、プロパティグリッド反映されないのはなぜなのでしょうか?



855:デフォルトの名無しさん
09/06/09 20:45:43
だってobjectだもの

856:デフォルトの名無しさん
09/06/09 20:46:32
肝心のプロパティを定義してないじゃないか

857:デフォルトの名無しさん
09/06/09 20:53:34
そうだった
objectじゃなくてもいいんだった

858:デフォルトの名無しさん
09/06/09 20:56:33
プロパティグリッドで使うだけなら本当に型を生成しなくてもTypeDescriptorで簡単にプロパティを追加できるよ

859:デフォルトの名無しさん
09/06/09 20:57:59
>>856の書いてるように、フィールドでは駄目だよ。
基本的には読み書き可能なプロパティを定義しないと。


860:デフォルトの名無しさん
09/06/09 21:04:18
プロパティを定義するならアクセサメソッドの実装を
ILGeneratorで生成しないといけないので超面倒だぜ

861:デフォルトの名無しさん
09/06/09 21:12:53
まあぶっちゃけDataSetに読み込んでDataRowViewを使えばいいんじゃないかなw


862:デフォルトの名無しさん
09/06/09 21:15:02
ここまでしてpropertygrid使う意味があるのだろうか

863:デフォルトの名無しさん
09/06/09 21:25:16
自分で作ることと総合的に考えれば、圧倒的に楽になる可能性はあるよ。
DataTableに一行目とかに読み込んで、DataRowView(DefaultViewでもいい)を取り出して、
1行目をPropertyGridにバインドすれば簡単なことならできる。
これで事足りれば、新しいクラスを作ったりTypeDescripter絡みを自分で処理する必要はない。


864:デフォルトの名無しさん
09/06/09 21:30:30
1行に1文字以上typoがあるはつは信用ならにゃい

865:デフォルトの名無しさん
09/06/09 21:31:39
CLR型やアセンブリを作り捨てしたらメモリリークするぞ

866:デフォルトの名無しさん
09/06/09 22:34:41
ちょっと教えてください。

ListViewのList表示で横スクロールするときになめらかにスクロール
させたいんだけど、どうすればいいんでしょうか。

エクスプローラみたいなスクロールじゃなくてFileVisorみたいなスク
ロールといえばイメージ伝わるかな。

ListBoxに無理矢理描画しようかとも思ったけど面倒だし、うまい方法
はないでしょうか。よろしくお願いします。


867:デフォルトの名無しさん
09/06/09 22:37:22
WPFに移行する

868:デフォルトの名無しさん
09/06/10 07:38:42
今勉強中なんですけど
カプセル化って隠すという意味ですよね?
デリゲートが何でカプセル化になるのか今一ピンとこないんですが

869:デフォルトの名無しさん
09/06/10 08:09:36
>カプセル化って隠すという意味ですよね?
多分違う

870:デフォルトの名無しさん
09/06/10 08:19:23
どのメソッドを呼び出すか?を隠してる

871:デフォルトの名無しさん
09/06/10 08:29:56
隠してない

872:デフォルトの名無しさん
09/06/10 08:41:45
ある意味隠してる

873:デフォルトの名無しさん
09/06/10 09:16:07
アクセス制限として見ると隠してないが、
カプセル化として見れば隠してる

874:デフォルトの名無しさん
09/06/10 09:51:36
>>868
雑だが
Commandパターン
クロージャ

875:デフォルトの名無しさん
09/06/10 10:27:40
ヘジたん的にはデザイナでコントロールクリック一発、それそこに書けを実現するための部品の一つでしかないんだろうな。
複数のメソッドが登録できるあたり、発想は明らかにクロージャー等ではないし、今ではクロージャー化しつつあるけど

876:デフォルトの名無しさん
09/06/10 10:38:35
小理屈よりも、まずやりたい事ありきというC#の考え方は嫌いじゃないです
IDEの支援を想定した文法とか、常識的にはこの文法冗長でだるいだろう普通やめるだろうというのが平気で入っている。

877:デフォルトの名無しさん
09/06/10 11:08:08
カプセル化も大きなウェイトを占める概念の一つであって
それがすべてじゃないと思うよ。

878:デフォルトの名無しさん
09/06/10 11:10:29
オブジェクト指向的にはメソッド一つだけのインターフェイスと等価
パターンとしてよく必要になるんだけど>>876の言うように面倒だから言語に取り込んだ

879:デフォルトの名無しさん
09/06/10 16:45:29
非同期実行する場合に

new Thread
ThreadPool.QueueUserWorkItem
BackgroundWorker
delegate.BeginInvoke
…ほかにもある?

なんか色々あって混乱するけど、どういう場合にどれを使えばいいの?


880:デフォルトの名無しさん
09/06/10 16:49:47
どうぞ
URLリンク(codezine.jp)

881:デフォルトの名無しさん
09/06/10 17:25:53
>>880
ありがとう、でももうちっと最近の記事じゃないとBackgroundWorkerとか扱ってないかも

private void BackgroundStart()
{
Action act = () =>
{
while (true)
{
Thread.Sleep(50);
Console.WriteLine("にゃー!");
}
};
act.BeginInvoke(null, null);
}

static void Main(string[] args)
{
BackgroundStart();
while (true)
{
Thread.Sleep(50);
Console.WriteLine("わんわん!");
}
}

今はこんな感じで書いてるけど、可読性いいのかこれ?
BackgroundWorkerはいろいろリッチだけど、使うの難しそう。

882:854
09/06/10 17:31:56
どうもありがとう filed ではなくて property をつくったら見事意図したとおりにできました!

最後にひとつ。
動的に作ったクラス、のインスタンスのプロパティに値を設定するには
どうすればよいですか?
もしくは、PropertyGird をプログラム側から操作して、PropertyGrid.SelectedObject
のプロパティを変更することはできますか?


883:デフォルトの名無しさん
09/06/10 17:44:41
リフレクションを使う
プロパティを生成できた奴がそんな質問をするなんて考えられないと思うんだが

884:デフォルトの名無しさん
09/06/10 17:48:08
わざとだろ、自分で考えろ以上終了だな

885:デフォルトの名無しさん
09/06/10 21:30:56
ボスケテー


AA作成支援ソフトっぽいもの作ってまして
標準環境(URLリンク(www.geocities.co.jp)
で指定した文字列の表示幅を取得する方法を探してます

Graphics.MeasureStringや
TextRenderer.MeasureTextなんかを使えばいけるんだと思うんですが
どーにもIE標準環境の作り方がわかりません(Graphicsオブジェクトどーやってもってくるの?)

おせーてくださーい

886:デフォルトの名無しさん
09/06/10 21:37:54
onpaintとかのじゃだめなのかな?

887:デフォルトの名無しさん
09/06/10 21:48:23
普通にControl.CreateGraphicsでもいいしGetDCしたのからFromHdcでもいいし

888:885
09/06/10 22:50:23
何が文字列の表示幅を決定している要因なのかよく理解していないものでして
てっきりGraphicsオブジェクトのプロパティに大きく依存するのかと思ったんですが
今メンバ見てもそれっぽいもの無いみたいですね。。


例えば下の二つの文字列

「ああああああ」
「..............................」

を長さ測定関数に渡した時に同一の値が帰ってくるような
状態をとりあえず目指していろいろやってるんですが
なかなかうまくいかないですね・・・

とりあえずもうちょっと調べてみますー

889:デフォルトの名無しさん
09/06/10 23:12:03
フォントだよ

890:デフォルトの名無しさん
09/06/10 23:33:33
あー
なんとかできたっぽいです
同じフォントでも環境によって表示のされ方違うのかと思ってました

レスくれた方ありがとでしたー

891:854
09/06/11 00:54:54
以下のようにしたらうまくいきました
リフレクターというヒントをくれたかた、どうもありがとう
Type type = (Type)MyClass;
type.GetProperty("x").SetValue(propertyGrid.SelectedObject, 1234, null);

いままでずっと C をやっていて C# も .Net おとといはじめたばかりなので、
ヒントがなければライブラリのどこに何があるかさっぱりわかりませんでした。
どうもありがとう!

892:デフォルトの名無しさん
09/06/11 01:01:32
どういたしまして
お役に立てて光栄です

893:デフォルトの名無しさん
09/06/11 07:42:51
質問者の笑顔のために

894:デフォルトの名無しさん
09/06/11 08:25:30
>>881
> Action act = () =>

なんぞこれ

895:デフォルトの名無しさん
09/06/11 08:38:37
lambda式でしょ。

896:デフォルトの名無しさん
09/06/11 13:05:26
>>894
actという名前の変数はAction型
() => {...} はAction型のリテラル(ラムダ式)で,空の引数を受け取って何かしてる

897:デフォルトの名無しさん
09/06/11 17:52:31
C#のAAはこれでおk?
(c_c#)

898:デフォルトの名無しさん
09/06/11 22:31:35
C#の式として有効なものしか認めない

899:デフォルトの名無しさん
09/06/11 22:56:39
>>897
//(c_c#)

でOK

900:デフォルトの名無しさん
09/06/11 22:57:17
"(c_c#)"

901:デフォルトの名無しさん
09/06/11 23:33:06
(^c_^#)

902:デフォルトの名無しさん
09/06/11 23:42:17
(T_T)=>("^A^")

903:デフォルトの名無しさん
09/06/12 11:28:58
*/

904: ◆BOHwjyHW6o
09/06/12 12:24:43
完全にハマりました。
質問させてください。

今、S/C間の通信プログラムを書いています。
--------
//↓サーバー側プログラム
this.mListener = new TcpListener(IPAddress.Any, 58201);
this.mListener.Start();
clTCPClient = this.mListener.AcceptTcpClient();
--------
//↓クライアント側プログラム
TcpClient tcp = new TcpClient();
tcp.Connect("①", 58201);
--------
①をlocalhostにすると接続が確認できます。
①をグローバルIPにすると接続できなくなります。
SocketExceptionが出ました。
ErrorCodeは10061
エラーメッセージは「対象のコンピュータによって拒否されたため、接続できませんでした。①:59201」と出ました。


905: ◆BOHwjyHW6o
09/06/12 12:26:01
ポートが空いていないのだろうと思い、
URLリンク(www.navnav.jp)
ココでポートの解放チェックを行いました。
結果、ポートは空いていました。
(ポート解放用と思われる接続もサーバー側のAcceptTcpClientでキャッチできました)

①をグローバルIPにして接続を行いたいのですが、どうすれば良いでしょうか?
また、何を確認すべきでしょうか?

環境は以下の通りです。
・PCは1台でテストしています。(OSはXP)
・Visual Studio 2008 で開発を行っています。
・ウィルスバスターは終了させた状態です。
・ルーターはフレッツ光のCTUです。
・ハブはBUFFALOのAirStationをルーターOFFモードで利用しています。


906: ◆BOHwjyHW6o
09/06/12 12:28:30
すいません。エラーメッセージ間違いました。

正しくは、
「対象のコンピュータによって拒否されたため、接続できませんでした。①:58201」
です。

よろしくお願いします。

907:デフォルトの名無しさん
09/06/12 12:33:04
どこか上流でファイアウォールでも動いているんじゃない?

908:デフォルトの名無しさん
09/06/12 12:37:08
ん?
ルータの内側にいるのに,外側のIPに接続しようとしてる?
ルータの実装によるけど,ふつーはつなげないんじゃないかな

909: [―{}@{}@{}-] デフォルトの名無しさん
09/06/12 12:41:36
NAPTしてるのを適切に処理してないって落ちじゃないの

910:777
09/06/12 13:12:08
SqlConnectionStringBuilderでAttachDBFilenameだけをクリア
したいのですが、ヘルプ通りnullを渡すとエラーになります。
他にどんな方法があるんでしょうか?

911:910
09/06/12 13:13:29
申し訳ない。
>>910の名前間違いです。777ではありません

912:デフォルトの名無しさん
09/06/12 13:19:59
SqlConnectionStringBuilder strbld = new SqlConnectionStringBuilder();
strbld.AttachDBFilename = "";

913:910
09/06/12 13:24:23
>>912
やっぱりそれしかないんですね。
最終的な文に"AttachDbFilename=;"が入っちゃうんで消せないかなと
思ってたんですが、そうしておきます。ありがとう。

914: ◆BOHwjyHW6o
09/06/12 13:41:29
>>907-909
返答ありがとうございます。
色々試行錯誤しているのですが、結局駄目でした。
localhostで作業を進め、サーバー立ては次の機会に行います。
ありがとうございました。

915:デフォルトの名無しさん
09/06/12 15:13:46
試行錯誤ってルーターを別の機種にするしか無いんじゃ・・・

916:デフォルトの名無しさん
09/06/12 16:13:14
フレッツ光のCTUは変更できないよ。
専用ルーターだから。

917:デフォルトの名無しさん
09/06/12 19:44:54
>>905
そういうルータ越しの環境だと、自分とこからグローバルIPアドレスでルータを越えてまた自分とこにくる通信は無理だと思う。
クライアントを別の回線(携帯とか友人宅・会社・学校)からやってみたらどう?

918:デフォルトの名無しさん
09/06/12 22:28:23
VS2008Pro、WinXPPro、C#で開発しています。
単体テストの機能を始めて使ってみたのですが、これには
「あるディレクトリ以下にある全てのデータファイルでテストを実施する」
という総当り的な、機能は付いているのでしょうか?

csvで、テストケースを一個一個作成していくのも面倒なので、個人的にはデータファイルを作って、
それをあるディレクトリ以下に放り込めば、勝手にテストしてくれるような機能を期待していたのですが……
やはり、自前で作るしかないですかねぇ。とはいっても、自前で作ってるのは、すでにあって、
今回はそれを既製品に移行しようという話なので、自前で作る云々になると話がズレて来るんです。

どなたか回答をお願いします。

919:デフォルトの名無しさん
09/06/12 22:45:39
自分の場合、ひかりone(旧テプコひかりからの移行なのでちょっと構成が違う)で
「光モデム」-「ルーター(ヤマハ)」-「サーバーやらクライアントやら」
って構成でグローバルIPアドレス指定で内部のクライアントからサーバー見えてるよ

920:デフォルトの名無しさん
09/06/12 22:50:22
>>914はflet'sつまりntt製のモデム兼ルータってことじゃないかと

921:デフォルトの名無しさん
09/06/12 23:13:48
>>913


SqlConnectionStringBuilder strbld = new SqlConnectionStringBuilder();
strbld.AttachDBFilename = "";



SqlConnectionStringBuilder strbld = new SqlConnectionStringBuilder();
strbld.Remove("AttachDBFilename");

922:デフォルトの名無しさん
09/06/13 21:45:53
フォルダが「共有フォルダ」かどうかを知ってアイコンに手のマークを
付けるにはどうしたらいいか知りたく。

「共有フォルダ」の一覧を得るには
System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_Share");
これでいいという情報は得ましたものの、これでなくてDirevtoruInfoのAttributes
のように高速で一発でわかる方法があれば尚ありがたく。

またアイコンに手のマークを付けるにはどのようにするものでしょう、
ご指導をいただきたく。


923:デフォルトの名無しさん
09/06/13 21:52:29
別管理なんだから、なんたらInfo からじゃ取れないだろ。
まっとうにやるなら、NetShareEnum() だな。それほど遅くない。

オーバーレイは ImageList_SetOverlayImage() とかで。

924:デフォルトの名無しさん
09/06/13 22:23:34
>>923
おお!!そういう方法があったのですか!
ありがとうございます。勉強してみます!!
助かりました!


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch