C#, C♯, C#相談室 Part94
■ このスレッドは過去ログ倉庫に格納されています
!extend:checked:vvvvv:1000:512
■Visual Studio 2017 Community(無償の統合開発環境)等はこちら
http://www.visualstudio.com/downloads/
■コードを貼る場合はこちら
http://ideone.com/
■前スレ
C#, C♯, C#相談室 Part93
http://mevius.5ch.net/test/read.cgi/tech/1492818720/
■次スレは>>970が建てる事。
建てられない場合は他を指定する事。
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured makefileとかだと依存関係が正しくなくて差分ビルドのつもりでも全ソース
フルビルドになっていたとかあるけど
あと、サードパーティーのコントロールとかって話なので、パッケージが
なんでも無条件にフルビルドするので、自分の修正とは関係ないところで
ガンガンビルドがはしっているとか VisualStudio2019のクエリビルダー使ってFillを生成してるんですが、
クエリビルダーの「クエリの実行」ではパラメータに「%」使って目的のデータを取得出来るのに
生成したFillの「データのプレビュー」でパラメータに「%」使うと何もヒットしないという現象が起きてて途方に暮れてます
ちなみにアンダースコアは任意の1文字で検索してくれるので初心者女子高生の私には
もう原因さっぱり判りませんの(´・ω・`) 自力で簡易なセキュリティソフトを作りたいと思っています。
動きは単純で、登録されていない実行ファイルが勝手に外部に通信しようとしたらブロックするだけのものです。
AVASTがやってる動きです。
何らかのAPIをフックするのだろうという事は想像できますが、取っ掛かりが分かりません。
どのAPIを見れば良いのかご存じの方いらっしゃいますでしょうか? Windowsの話だったらWindows Filtering Platformとか wpf でtabcontroleで複数タブにrediobutton配置支店ですけど
これを全部一つのグループにすることってできないんですかね?
groupname指定しても駄目だったので仕様的に方法なしなんでしょうか……(´・ω・`) GroupNameでは無理
IsCheckedへのバインディングとかでうまいことやって >>535
明らかにC#の範囲外の質問でOSハックレベルの話だが、例えばWindowsならカーネルドライバを利用した通信フックライブラリはいくつかあったはず
んでTCPやUDPのソースポートから発信元プロセスは特定できるからそれくらいならすぐ作れるだろうけど
想像以上に多くのシステムプロセスが通信してるから登録するのめんどそうだけどな >>539
バインディングなんてわかるわけ無いだろ!(`;ω;´)
もう仕方ないからボタンと背景色でタブっぽい見た目作ってラジオボタンをVisibleったりhiddenったりしてそれっぽいの作った…… functorに関する質問です
C++で次のように書いとけば
template<typename Functor>
double Example( Functor func,・・・){
呼出し時に、引数funcに関数へのポインタでも、ラムダ式でも、関数名でも記述できますが、
C#で同じように、引数に、デリゲートでもラムダ式でも関数名でも記述可能にするにはどーすればいいのでしょうか? > 引数に、デリゲートでもラムダ式でも関数名でも記述可能にするには
デリゲート型を指定すればいい
double Example<T>(Func<T, double> func, T obj) { ... }
double ToDouble(Hoge hoge) { return hoge.Value; }
this.Example(obj => obj.Value, hoge);
this.Example(ToDouble, hoge);
this.Example(new Func<Hoge, double>(ToDouble), hoge);
ただしシグネチャが同じでもデリゲート型が違うと無理なのでラムダ式なりとおす必要がある
delegate TRet Converter<TArg, TRet>(TArg arg);
var conv = new Converter<Hoge, double>(obj => obj.Value);
this.Example(conv, hoge); // エラー
this.Example(obj => conv(obj), hoge); // OK System.Collections.Generic.List<System.String> hips =
new System.Collections.Generic.List<System.String>(0);
hips.Add(@"尻");
hips.Add(@"ケツ");
hips.Add(@"Buttocks");
hips.Add(@"んまら");
hips.Add(@"臀");
hips.Add(@"ω");
hips.Add(@"Hip");
foreach (System.String hip in hips) {
System.Console.WriteLine(hip);
} 俺のツレの先輩がc#プログラマに酷い目に遭わされたことがある
c#プログラマから金借りて返さんかったら、拉致られて拷問うけた
指の爪全部ペンチで剥がされてその後ペンチで指先を挟んで潰されたらしい
4本目くらいで痛みに耐え切れなくて舌噛み切って死のうとしたけど死ねなかったって
命までは取られなかったけど指先全部駄目になって切断したみたい メモリ不足での相談です
小さいjpg画像ファイル(1ファイル50KB程度)を10,000ファイル程度
サードパーティ製のGridViewに投げ込んで表示させようとしてます
その前にList<Image>に下のような感じでStreamで投げ込んでいくのですが
var fs = System.IO.File.OpenRead(@filepath);
ListData = new Bitmap(Image.FromStream(fs, false, false));
fs.Dispose();
4000ファイルあたりでメモリ不足に陥ります
VSの診断ツールで見ていると、読み出しはじめて4GBで止まります
メモリが4Gでアウトになっているのは理解できるのですが
ローカル上のファイルの総データ量は800MB程度で、実際に読み込みがとまるあたりでは
せいぜい200MB程度読み込んだ程度と思います
2000ファイル程度にグループごとに都度分けて読み込ますしかないかなと思っていますが
確認すべき点(余計に容量食っている要因)やなにか他に方法があったらご教授ください >>548
JpegをBitmapに展開してるのだから容量が増えるのは当然では >>549
レスありがとうございます
同サイズ程度のbmpファイルもあるのでそっちでやってみましたが
4000ファイルが6000ファイルくらいに限界数が若干のびだだけでした 32bit優先が付いてるとか?
ただどっちみちアプリ全体どころか、1つのリストで4Gもメモリに保持とかは筋がめっちゃ悪いぞ。
4000ものフル画像が同時に必要とかあり得ないし。
表示上必要ならメモリ上にもつならすごく小さなサムネイルをダイナミックに並列処理で作りながら持つとか。
今表示に必要なものだけ、ダイナミックにメモリで並列処理でサムネ作るとかでしょ。 今時VirtualMode的なものが無いグリッドコントロールなんてあるのか? >>552
やっぱり、そうですよね
実際には10000ファイル越える予定だったのでなおさらですよね
スクロール時のスピード感は多少落ちますが
素直にグリッドコントロールが描画する際に都度読み込むようにすることにします >>554
良い悪いは置いておいて、とりあえずファイル郡をまとめて読み込んでおくのが
目的で、Bitmapで変換するとメモリを消費してしまうのならば、ファイルの内容を
Streamの配列に読み込んでおいて、表示するときにBitmapで変換するとか
そして表示するだけならばBitmap使わなくてもImageでStreamから読んで
DrawImageでよいんじゃないかなとか 要するにサムネ表示したいんだろ
SSDなら1万ファイルの読み込みにもそんな時間掛からんし
ファイルをインデクス化して画面に出る部分だけ都度読み込んで描画すればいい
グリッドビューなんて必要かね 仮想化すればいいだけの話じゃん
何兆個のファイルがあろうとどうせ表示される項目は多くても数十なんだからスクロール位置などから表示すべきファイルだけサムネ表示すればいい 日本語の変数名使えるのに記号の変数名はダメなのかよ
競馬関係のアプリ開発受注したから予想記号の変数名として分かりやすく記号使いたいのに enumの値とかならまあわからなくもないかな
enum 予想記号 {◎, ○, ▲, △, ☆, ☓};
var 予想 = ◎;
https://umasiru.com/wp-content/uploads/2019/03/IMG_4633-2.jpg フォームを開いてその画面での処理中に
Form fs = new FormA;
try{
fs.ShowDialog(); ←ここ
}
catch{}
ここのところでハンドルされてないエラーがでて止まります
FormAでの例外処理などには一切ひっかからず
この場合解決の道筋はどこからでしょうか
ちなみにFormAではwebview2でオフィス365のウェブ版エクセルの新規作成を開こうとするとエラーになります
ワードではでないのですが
ここででるエラーは、System.Runtime.interior services.COMEException
0x8007139Fです >>564
まず意味が分からんけどFormなの?Dialogなの? >>566
すみません、書き間違いです
Form fs = new FormA();
>>565
ググったのですが、webview2がnullなってるのだろうと考えられるくらいで、同じケースはなかったです
そもそもなんでワードは開くのにエクセルはwebview2がnullになってしまうのかわからず、どこの時点でそうなるのか調べたいのですが、FormA側ではcatchできず、上の位置で停止するんですよね それ以前の根本的な問題があるのだろう
君には無理とは言わないがしばらく距離を置こう 変な所でフォーム表示しようとしてんじゃね
そのコードだけじゃなくてメソッドごと見せてみ >>569
FormAにはwebview2を配置していて、ブラウジングさせています
通常のサイト閲覧は何も問題ないのですが、ブラウザ上でエクセルが開けるoffice365を使用中、新規作成で開くときだけ呼び出し元のフォーム(上でこことしたところ)で停止します
既存のエクセルファイルなんかはFormA上のwebview2できちんと開けているのですが
なので、自分で書いた特定のメソッド中のエラーではなく、ページ遷移中に停止し、呼び出し元のShowdialogのところに戻ってハンドルエラーになってしまいます 再現する最小コードを作る
それでも不明ならその最小コードを公開して質問 ゲイツが収入マイナス7兆円ぐらいで苦しんでる。
c# プログラマから金を集めて、ゲイツに寄付するべきだと思う。
損失の一部 5兆円ほどc#プログラマから強制的に集めたい。国内に5万人ぐらいc#プログラマはいるから、1人1億ぐらい払えばいい。
土地とか家を売ればこんぐらい払えると思う。
払えないひとは肝臓とか売ればいい。 >>572
では早速言い出しっぺのあなた様から肝臓を差し出して下さい DBから取得した重複なしの文字列List (要素数約4000) をComboBoxのDataSourceにセットする処理が、
約900ms〜1100msかかり、その間Formが固まるのですが、どうすれば固まるのを回避できるでしょうか。
A5M2でSELECTクエリの所要時間を見ると、だいたい700ms〜900ms台で、ここは改善のしようがなさそうです。 ComboBoxで4000の中から選ぶのは大変そうだな
DataSourceに設定する前後にComboBox::BeginUpdate/EndUpdateを呼べば多少は改善すると思う
それ以上はComboBoxじゃ無理じゃないかな 仮想モードもないし >>578
DBから取得する部分を別スレッドで動作するasyncメソッドにするです
UIの更新は別スレッドなのでInvokeで awaitしとけばUIスレッドに戻ってくるからInvoke要らんだろ みなさんありがとうございます。
BeginUpdateとEndUpdateで20〜40msほど早くなりました。
現状、DBからの取得部分は別スレッドにしています。
ただし、フォーム表示時に、
@ComboBox の DataSource に List をセット。
A別の個所で設定した値で、ComboBox.SelectedItemを決定。
BComboBox.SelectedItem に応じて、それに対応するデータを DataGridView に表示。
という処理をしているので、結局ComboBoxへのDataSourceセット待ちになります。
むしろUIと同じスレッドでデータ取得すればスレッド切り替え処理がなくなって微妙に高速化出来るんじゃ?と思ってます。 データ取得をUIスレッドで行ってみましたが、別スレッドでしたケースと比較して、実行するたびに優劣変わる程度でした。
これ以上の改善は無理そうなのでいったん諦めます。 Formが固まるのを回避したいってのは高速化したいということだったのか・・・
ま、がんばって >>578
転送時に圧縮かけたら高速化するんじゃね
構成わからんからあてずっぽうでいうけど
DBサーバと近いWEB鯖のPHPでデータ一覧取得してJSONとかで転送(要するにPHPでAPI作成)
サーバの設定等でHTTP圧縮をON
圧縮かかってるから転送そのものが高速化される
どうやって圧縮かけるかは他にも色々やり方あるだろうけどね
LAN内に全てそろってる(例えば同一PC内)としてもかなり速くなるはずだよ
クエリで700msってのが気になるけど時間かかりすぎじゃないかな
Explainみた?
プロファイラはどう?昔はEQATEC Profiler使ってたけど今は何がいいんだろうね
どこにどれぐらいの時間がかかってるかわからないと理論値と比較できない
初見の感想は4000件程度で700msもかかってるのが気になる
応答だけ?それとも結果の羅列まで込みの時間かな
クラサバでそんなにかかる処理ってあまりないと思う そもそも一瞬で取得すれば固まらないからね
あとはUIに先回りして裏で取得するとか、DB側でキャッシュするとか、小出しにしていくとか・・・
まぁ、一番簡単なのは画面にプログレスバー出してめっちゃ高速に処理してる風を装う事とかだけど
ただ、何も知らずに直観でいうと100msは切るはず 実処理時間と言うより、
取得中に割り込み入れないと固まったように見えるってだけの話では 時間が掛かっているのはデータ取得の部分じゃなくて
取得したデータをコンボボックスに渡す処理(>>584の@)だから
>>579が全てだな たぶん「犯人」はComboBoxだろうが一応問題の切り分けが必要だと思って
public Form1()
{
InitializeComponent();
var asm = Assembly.GetAssembly(typeof(Form));
var bl = new BindingList<Type>();
foreach (var item in asm.GetTypes()) bl.Add(item);
var sw = Stopwatch.StartNew();
comboBox1.DisplayMember = "Name";
comboBox1.DataSource = bl;
Console.WriteLine($"Time = {sw.ElapsedMilliseconds} ms, Number of Items = {bl.Count}");
}
こんなコードを書いてみた。10年前のポンコツPCで実行してるが約2400個のアイテムをぶち込むのに
デバッグモードでも10ms程度の時間しか掛からない。
つまり「犯人」はComboBoxじゃないんじゃないの?知らんけど。 >>591
フォームのコンストラクタで測ってるけど、フォームがロードされた後で測るとかなり変わるよ
うちの環境ではデバッグビルドで、コンストラクタ:3msec、Loadイベント時:226msec DB の実行計画を見れば?
インデックスを使わずに、全件探索でもしてるのでは?
2分探索なら、2 ^ 10 = 1,024
2 ^ 12 = 4,096
つまり、12回探索するだけ
ミックの本でも読んだ方がよい インデックス張ったら挿入や更新の度に毎回ソートしてるとでも思ってるんだろ 約900ms〜1100msの処理のうち
クエリが700ms〜900ms台で、改善のしようがないっていってるんだから
それがホントなら速度的なものはどうしようもないと思うんだが
画面が固まる対策ならクエリを非同期に(正確にはUIスレッド以外で、か)しろで終わりだろ ルビおじに絡むおじさんはルビおじよりさらに無能だからな >>600
それWPF
>>578はWinFormsみたいだけど WinFormsのComboBoxに仮想モード追加する例ってありそうで無いな じゃ俺がWinFormsのComboBoxを仮想化する知恵を貸そうか? みなさん本当にありがとうございます。
原因は、約4000の要素をDBから取り出す所要時間でした。
約60万レコード内の、文字列カラムのデータを、重複しないように、GROUP BYする処理が時間食ってました。
なので、該当の文字列カラムだけを重複なしで格納するキー一覧テーブルを作り、
データINSERT時に、キー一覧テーブルの既存レコードと一致しない文字列だけをキー一覧テーブルに追加するトリガー処理を作りました。
そして、ComboBox の DataSourceにはそのキー管理テーブルのデータをセットするようにして、表示所要時間を5〜6割短縮出来ました。 高々60万レコードの group by に700msって遅くね?
DBMS 何使ってるのかわからんけどインデックス張るだけで良いような気もするが… GROUP BY自体が遅いもんよ
SQLが悪いとインデックス使っても無視されてFULL検索になってしまう それより結局ComboBoxは何の関係もなかったってことだよね?
つまりボトルネックがどこにあるのか計測して確認もせず思い込みで
ComboBoxが悪いとミスリードな質問をした。
ここは反省して欲しい。 最初の質問で問題の処理に約900ms〜1100msかかっていてそのうちクエリの所要時間が700ms〜900ms台と書いていて、その上でクエリ以外の部分(約200ms)を改善したいという話だったから測ってないわけではないかと
クエリ部分は改善不可能と思い込んでたのはあるが >>611は毎度お馴染みで皆さんご存知の、
ComboBoxに責のあるマイクロソフトの犬 最初に戻ると結局画面は固まってなかったってことなんだろうな
これが一番のミスリード FormのLoadで何も表示されないまま1秒以上かかるとかなり固まった感は強い
だからスプラッシュやプログレスバーというのは非常に大事
これがあるだけでクレーム率はかなり下がる
速度最適化というのは実際のレスポンスやスループットだけではなくて
体感速度も最適化するべきなんだ いや、クエリの間は固まってたんじゃね
そういう意味ではコンボボックスは無関係だな 別スレッドでの取得結果を待たずにコンボボックスが表示できるとは知らんかった >>621
それが期待する動作だったとは読み取れなかったわ… なるほど
同期で待つのと非同期で待つ違いがわかってなかったのか >>613
なるほどね。読み返してみると確かにそういう風に読めないこともない。
でもその解釈だと辻褄が合わないように聞える部分もいろいろあるね。
まあ揚げ足取りは本意じゃないのでこれで >>610
group by の動作原理考えればそうでしょう
ソートと集計の複合技でっせ
EFを初心者に進めたくないのがその辺りかな
実行計画取れやと言いたくなって来る ■ このスレッドは過去ログ倉庫に格納されています