C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: C#についての質問です。


(過去ログ 127 を表示中)

[トピック内 22 記事 (1 - 20 表示)]  << 0 | 1 >>

■75544 / inTopicNo.1)  C#についての質問です。
  
□投稿者/ ぽん吉 (9回)-(2015/04/07(Tue) 14:32:20)

分類:[.NET 全般] 

前回にも同様の質問をさせていただいたのですが、もう一度同じ質問させてもらいます。

C#でツール開発をしており

string gg = System.Text.Encoding.GetEncoding(932).GetString(TargetByte2);

string gg1 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte3);

string gg2 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte4);

string gg3 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte5);


文字列を凍結するプログラムを
timerをかけて、ツール側のテキストに表示するツールを開発しているのですが、
数回表示するとフォームがフリーズしたままずっとそのままです。
どうすれば文字を凍結してフリーズしないようにできますでしょうか?
timerは1秒間毎に文字列を表示するようにしています。
当方知識があまりなくてどうしようもないので詳しい方お手数ですがご教授頂ければ幸いです。
引用返信 編集キー/
■75545 / inTopicNo.2)  Re[1]: C#についての質問です。
□投稿者/ WebSurfer (538回)-(2015/04/07(Tue) 14:59:09)
No75544 (ぽん吉 さん) に返信

> 前回にも同様の質問をさせていただいたのですが、もう一度同じ質問させてもらいます。

そのスレッドの URL を書いていただけませんか?

そこに、

> 文字列を凍結するプログラムを
> timerをかけて、ツール側のテキストに表示するツールを開発しているのですが、

というところが具体的にどうなっているのか書いてあるのでしょうか?

もし書いてなければ、掲示板に書いてあること以外第三者は何も知り得ないということを
考慮いただき、情報を提供してください。できれば、問題を再現するのに必要最低限(余
計な部分を削除して、あくまで必要最低限でお願いします)のコードをアップしていただ
けると、回答者のほうで試して原因を特定でき、解決が早いかもしれません。

それから、質問する際はまず最初に、何を作っているのか(Windows Forms アプリ? 
Console アプリ? その他?)、ご自分の環境(OS, .NET, Visual Studio のバージョン
など)に関する情報を書いていただけませんか?

引用返信 編集キー/
■75546 / inTopicNo.3)  Re[2]: C#についての質問です。
□投稿者/ 774RR (252回)-(2015/04/07(Tue) 15:23:52)
http://bbs.wankuma.com/index.cgi?mode=al2&namber=74687&KLOG=125
だと思う。

で、俺も以下のようなプログラムを書いてみたけどフリーズしない。
C# .NET 4.0CP Console App VS2010 前後略
static void Main(string[] args)
{
    for (int i=0; i<1000000; ++i)
    {
        byte[] cp932_byte_seq = new byte [] { 0x83, 0x41 }; // ア
        string utf16_str = System.Text.Encoding.GetEncoding(932).GetString(cp932_byte_seq);
        Debug.WriteLine(utf16_str);
    }
}

Release で0秒(たぶん最適化で中身がなくなっている)
Debug + デバッガ無し実行で9秒
Debug + デバッガあり実行でフリーズしない(時間がかかるので途中で止めたけど)

GetEncoding/GetString は悪くないに1票。フリーズしているとしたら他に原因があると思われる。
Microsoft を疑っているのであればそこんところ string gg="hoge"; とかしてみりゃいい。
たぶんそれでもフリーズすると、俺は思うんだけど。

前にも言ったけど「ましなタイトル」つけておくれ。 stackoverflow.com だとマイナスモデ対象だよ。

引用返信 編集キー/
■75547 / inTopicNo.4)  Re[3]: C#についての質問です。
□投稿者/ ぽん吉 (10回)-(2015/04/07(Tue) 15:43:02)
開発環境はwindows8.1 pro

VS2013

C# formアプリケーション

文字凍結の中身は

対象プロセスのバイナリを取得していて、
バイナリを日本語に変換して、
半角カタカナを凍結させています。

ア イ ウ エ オ

みたいにばらばらで取得して

連結させたものを一覧で
ずらっと表示させています。

readprocessmemoryでバイナリを取得させています。

引用返信 編集キー/
■75548 / inTopicNo.5)  Re[1]: C#についての質問です。
□投稿者/ wakuwaku (3回)-(2015/04/07(Tue) 15:53:33)
> 数回表示するとフォームがフリーズしたままずっとそのままです。
> どうすれば文字を凍結してフリーズしないようにできますでしょうか?

フリーズとは「応答なし」のことですか?
表示が更新されないということですか?


timerを使ってるとのことなので前者は考えづらいですが。


画面が更新されないとしたらtimerスレッドからUIを更新しようとしているからでは?
更新処理はInvokeしてますか?
引用返信 編集キー/
■75549 / inTopicNo.6)  Re[4]: C#についての質問です。
□投稿者/ 774RR (253回)-(2015/04/07(Tue) 15:56:12)
> 連結させたものを一覧で
> ずらっと表示させています。

先の過去ログでも No74695 で指摘されてるぢゃん。
何も考えずに「文字列の連結」をしてしまうと性能が出ないよ。

引用返信 編集キー/
■75550 / inTopicNo.7)  Re[2]: C#についての質問です。
□投稿者/ ぽん吉 (11回)-(2015/04/07(Tue) 15:56:47)
フォームが応答なしの状態で、操作ができない状態です。

invokeは使ってないです。
引用返信 編集キー/
■75551 / inTopicNo.8)  Re[3]: C#についての質問です。
□投稿者/ wakuwaku (5回)-(2015/04/07(Tue) 16:02:12)
No75550 (ぽん吉 さん) に返信
> フォームが応答なしの状態で、操作ができない状態です。

UIスレッドで文字列連結のループをしながら timerスレッドで表示を更新したいってことですか?

もう少し詳細に説明していただくか、ソースの一部を開示してください。
引用返信 編集キー/
■75552 / inTopicNo.9)  Re[3]: C#についての質問です。
□投稿者/ shu (726回)-(2015/04/07(Tue) 16:10:19)
No75550 (ぽん吉 さん) に返信
> フォームが応答なしの状態で、操作ができない状態です。
>
処理に時間がかかっているか無限ループが考えられます。

コードをもっと判断出来る範囲まで提示したほうがよいです。
回答者が再現できなければ対策も出しようがない。
引用返信 編集キー/
■75553 / inTopicNo.10)  Re[4]: C#についての質問です。
□投稿者/ ぽん吉 (12回)-(2015/04/07(Tue) 16:15:09)

ReadProcessMemory(ProcessHandle, (IntPtr)slddl2, bytes, 4, out ptrBytesReaded);

int value74 = BitConverter.ToInt32(bytes, 0);//


ReadProcessMemory(ProcessHandle, (IntPtr)value74 + 0x4, bytes, 4, out ptrBytesReaded);

int value75 = BitConverter.ToInt32(bytes, 0);//


byte[] TargetByte2 = BitConverter.GetBytes(value75);

ReadProcessMemory(ProcessHandle, (IntPtr)value74 + 0x8, bytes, 4, out ptrBytesReaded);

int value71 = BitConverter.ToInt32(bytes, 0);//

byte[] TargetByte3 = BitConverter.GetBytes(value71);

ReadProcessMemory(ProcessHandle, (IntPtr)value74 + 0xC, bytes, 4, out ptrBytesReaded);

int value72 = BitConverter.ToInt32(bytes, 0);//

byte[] TargetByte4 = BitConverter.GetBytes(value72);


ReadProcessMemory(ProcessHandle, (IntPtr)value74 + 0x10, bytes, 4, out ptrBytesReaded);

int value73 = BitConverter.ToInt32(bytes, 0);//

byte[] TargetByte5 = BitConverter.GetBytes(value73);


string gg = System.Text.Encoding.GetEncoding(932).GetString(TargetByte2);

string gg1 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte3);

string gg2 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte4);

string gg3 = System.Text.Encoding.GetEncoding(932).GetString(TargetByte5);

string aa = gg + gg1 + gg2 + gg3;

各種アドレスを4バイトずつ足していき文字列を取得させています。

引用返信 編集キー/
■75560 / inTopicNo.11)  Re[5]: C#についての質問です。
□投稿者/ Azulean (461回)-(2015/04/07(Tue) 22:20:11)
No75553 (ぽん吉 さん) に返信

このコード自体にフリーズさせる要因は見当たりません。
繰り返している部分が予想以上に繰り返している、あるいは単に繰り返しているつもりが、呼ばれる回数を倍々にしてしまっているなど、他の単純ミスも疑われます。
タイマーのセット部分とか、次の表示ための準備の部分とかも示していただいた方が良いでしょう。
引用返信 編集キー/
■75573 / inTopicNo.12)  Re[6]: C#についての質問です。
□投稿者/ ぽん吉 (16回)-(2015/04/08(Wed) 17:54:32)

if
(value71 == 1)
{
//1
byte[] bytes = new byte[24];
IntPtr ptrBytesReaded;


textBox1.ResetText();
for (int cnt = 0; cnt <= 200; ++cnt)
{
int pointer = cnt * 4;
ReadProcessMemory(ProcessHandle, (IntPtr)sso1 + pointer - 6, bytes, 4, out ptrBytesReaded);

int value31 = BitConverter.ToInt32(bytes, 0);//
if (value31 != 0)
{
string enemyname = GetEnemyName(cnt);
textBox1.AppendText(Environment.NewLine + cnt.ToString("X") + (",") + value31.ToString("X4") + (",") + enemyname);
}

こちらのソースが、テキストに表示する部分なのですが、ここがフリーズする原因なんでしょうか?
引用返信 編集キー/
■75575 / inTopicNo.13)  Re[7]: C#についての質問です。
□投稿者/ wakuwaku (8回)-(2015/04/08(Wed) 21:58:33)
No75573 (ぽん吉 さん) に返信
>                         textBox1.ResetText();

>                                 textBox1.AppendText(Environment.NewLine + cnt.ToString("X") + (",") + value31.ToString("X4") + (",") + enemyname);

Invokeを利用せずに上記コードが問題なく動くということは、おそらくSystem.Windows.Forms.Timerをお使いかと思います。
System.Windows.Forms.TimerはUIスレッド上で処理しますので、重い処理をすると応答なしになりますよ。

System.Threading.Timer
System.Timers.Timer

上記どちらかのTimerを使用し、引用した処理をInvokeしてください。


また、読み込んだ文字列をリアルタイムに表示したい理由はありますか?
特に理由がなければ、読み込んだ文字列はStringBuilderのAppendメソッドで連結していき、
繰り返し処理の外でTextBoxに割り当てるのが良いと思いますよ。

引用返信 編集キー/
■75576 / inTopicNo.14)  Re[7]: C#についての質問です。
□投稿者/ Azulean (462回)-(2015/04/08(Wed) 22:15:14)
No75573 (ぽん吉 さん) に返信
> for (int cnt = 0; cnt <= 200; ++cnt)
> {

> textBox1.AppendText(Environment.NewLine + cnt.ToString("X") + (",") + value31.ToString("X4") + (",") + enemyname);

201 回も textBox1.AppendText する処理を定期的に呼ぶということであれば、「フリーズしても仕方ない」という認識を持ちます。
この処理を書いてもリアルタイムに更新されることは現実的にありません。


フリーズしているように見えるのは、「応答なし」表示かと思います。
これは、画面を更新する・マウスやキーボードなどのイベントに反応する義務のあるメインスレッドのメッセージループが処理しないことが理由です。
その原因は「イベント中の処理が長すぎること」なので、一般的には「イベント中の処理を短時間に終わらせる」か、「イベント中に処理を書かず、マルチスレッドで処理する」かです。


TextBox.AppendText は現在のテキストを取得し、指定された文字列を連結し、再度テキストを反映するといった流れになりますので、基本的に遅いです。
数度呼ぶ程度では大きな問題になりませんが、繰り返し呼ぶようなら、すでに提案のあるとおり、StringBuilder で表示文字列を組み立ててから、最後に一斉に反映を考えるケースです。

ただ、随時表示するなどの要求がある場合、タイマーで小分けに処理するか、マルチスレッドで処理するかを考える必要があります。
通常は後者なのですが、スレッドとは何か、どういったことに気をつける必要があるかの勘所がないと、まず失敗します。
自信がなければ、タイマーで小分けに処理することも視野に入れるべきでしょう。
たとえば、1回のイベントでは 10 ずつ処理するとか。(それで改善するかは不明です)
引用返信 編集キー/
■75577 / inTopicNo.15)  Re[8]: C#についての質問です。
□投稿者/ なちゃ (32回)-(2015/04/09(Thu) 10:34:08)
んー、この処理が無駄に重い処理になってるのは事実ではありますが、こんな程度の処理でずっとフリーズなんてのは考えられません。
明らかに別の原因があるはずと思います。
まあそれが今のコードじゃあまり想像つかんのですが。
引用返信 編集キー/
■75578 / inTopicNo.16)  Re[9]: C#についての質問です。
□投稿者/ wakuwaku (9回)-(2015/04/09(Thu) 11:13:02)
No75577 (なちゃ さん) に返信
> んー、この処理が無駄に重い処理になってるのは事実ではありますが、こんな程度の処理でずっとフリーズなんてのは考えられません。
> 明らかに別の原因があるはずと思います。
> まあそれが今のコードじゃあまり想像つかんのですが。

> timerは1秒間毎に文字列を表示するようにしています
と、ぽん吉さんがおっしゃっているように、
System.Windows.Forms.Timerが(実際はわかりませんが)1秒間隔でTickイベントを発生させているようです。

確かにずっとフリーズするほどの処理ではないですが、イベントハンドラ内の処理が1秒以内に終わらないと、
次のTickイベントが発生、また次のTickイベント発生となって、メインスレッドがビジーになり
処理がUIに返ってくることはないような気がするのですよね。

要は「シングルスレッドでやる処理じゃない」ということですかね。
引用返信 編集キー/
■75580 / inTopicNo.17)  Re[10]: C#についての質問です。
□投稿者/ なちゃ (33回)-(2015/04/09(Thu) 13:08:40)
いや、テキストボックスに200回程度短い文字列を追加するのに1秒以上もかかるわけがないのではと言う話です。
これはこれで問題あるとしても。
いや試してないから実はかかったらびっくりですが。
※UIの操作によってはびっくりするような現象はあり得るんですが、テキストボックスはあまりそういうのなかったように思います。
引用返信 編集キー/
■75583 / inTopicNo.18)  Re[11]: C#についての質問です。
□投稿者/ wakuwaku (11回)-(2015/04/09(Thu) 14:00:20)
No75580 (なちゃ さん) に返信
> いや、テキストボックスに200回程度短い文字列を追加するのに1秒以上もかかるわけがないのではと言う話です。
> これはこれで問題あるとしても。
> いや試してないから実はかかったらびっくりですが。
> ※UIの操作によってはびっくりするような現象はあり得るんですが、テキストボックスはあまりそういうのなかったように思います。

「文字列を200回追加する」のに1秒かかるわけでなく、「ハンドラ内のすべての処理」に1秒程度かかってるのではないかということです。


メインスレッド上でハンドラを処理というとこは、軽い処理なら

Tick1!!→ハンドラ開始1→ハンドラ終了1→UI処理→Tick2!!→ハンドラ開始2→ハンドラ終了2→UI処理

という感じになるはずですが、メモリ読んでコンバートしてコントロールに反映云々を200回するわけですから

Tick1!!→ハンドラ開始1→ハンドラ終了1→(UI処理する暇もなく)Tick2!!→ハンドラ開始2→ハンドラ終了2→Tick3!!

となって、いわゆる応答なしになっているのでは?ということです。
引用返信 編集キー/
■75585 / inTopicNo.19)  Re[12]: C#についての質問です。
□投稿者/ なちゃ (34回)-(2015/04/09(Thu) 15:02:01)
なんか否定ばっかりしてるみたいですみません。

そこはその通りなんですよ。
話の流れを見ていただくと分かるかと思うんですが、私は単に、テキストボックスへの追加の仕方が原因という感じの流れについて、それが原因ではなかろう、原因は他にあるだろう、と言っているだけなのです。

なんか紛らわしくてすみません。
wakueakuさんが書かれてるテキストボックス意外の処理も、その他の原因に入ってるイメージです。
引用返信 編集キー/
■75586 / inTopicNo.20)  Re[13]: C#についての質問です。
 
□投稿者/ wakuwaku (12回)-(2015/04/09(Thu) 16:06:46)
No75585 (なちゃ さん) に返信
> なんか否定ばっかりしてるみたいですみません。

いえいえ。意見を交わすのに否定も何もありませんよ。

> 
> そこはその通りなんですよ。
> 話の流れを見ていただくと分かるかと思うんですが、私は単に、テキストボックスへの追加の仕方が原因という感じの流れについて、それが原因ではなかろう、原因は他にあるだろう、と言っているだけなのです。
> 
> なんか紛らわしくてすみません。
> wakueakuさんが書かれてるテキストボックス意外の処理も、その他の原因に入ってるイメージです。

そういうことでしたか。
原因は多分「メインスレッドで重い処理をしている。」ってことなんですけど、根本的な原因がTextBoxにあるような流れになってますね;

今試しに

timer.Tick += (x, y) => {  for (int i = 0; i <= 200; ++i) {  System.Threading.Thread.Sleep(10); } };
timer.Interval = 1000;
timer.Start();

を実行してみたら応答なしとまではいかないにしてもカックカクで操作できたもんじゃありませんでした。

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -