C#, C♯, C#相談室 Part93©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
■Visual Studio 2017 Community(無償の統合開発環境)等はこちら
http://www.visualstudio.com/downloads/
■コードを貼る場合はこちら
http://ideone.com/
■前スレ
C#, C♯, C#相談室 Part92
http://echo.2ch.net/test/read.cgi/tech/1485589613/
■次スレは>>970が建てる事。
建てられない場合は他を指定する事。
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured >>22
EWX_FORCEとかEWX_FORCEIFHUNGを指定してるんでしょ
https://msdn.microsoft.com/ja-jp/library/cc429713.aspx
セキュリティアップデートは確実にリブートする必要あるから多少の犠牲はやむを得ない
って思ってるんじゃね? ExitWindowExの英文説明では、DWORD dwReservedのとこがdwReasonになってんね。
このへんかな プロセスの終了確認はあるだろうか、その結果タイムアウトした時のスレッドの落とし方はものすごい強引だった気がする。
昔shutdown -s -t 01で落として確認した事ある。 OSの仕様なのか.NET独特の挙動なのか>>23みたいな話なのかはっきりしないな
.NET独特の挙動だったら業務でアプリ作っている人は死活問題じゃね >>26
日本語版のドキュメントが更新されてないだけみたい
WindowsXPからdwReasonになってる いやいやデフォではプロセス強制終了なんてないよ絶対w
Winduws Updateはデフォでは自動になってるんだから、Windows Updateが走るたびに
そんな無茶苦茶やってたら世界中で大騒ぎになってるってw
XPの時代はそんな経験したような記憶もあるけど
少なくともVista以降はないと思うよ 俺は趣味でやっているだけだしアップデートも任意のタイミングでしかやらないからどうでもいいが
VSの有料ライセンス買っている人がいて心配だったら直にMSに聞いた方がいいな >>28
業務アプリが走るような環境は、社内でKB単位で配布して、ログイン前に当たるようにしてると思う。
>>30
本人はプロセスじゃなくてスレッドを問題視してるのでは? >>30
10以前はWindowsUpdateをするタイミングをこちらの問題の無いタイミングで出来たから
そもそも問題自体が存在しなかったという事実。 適度にトラブル起こしてあげないと窓際族の情シスの仕事がなくなっちゃうからね >>27
これは良いこと聞いた。
うちも似たような仕組み作ってるグループあるから、ExitWindowsExも利用して調査してみるよう伝えてみるわ >>36
UIスレッドでメッセージボックス出しとくと、プロセスを落とす正規ルートからはずれて再現できるとか、なんか色々こねくり回したよ。
今だと仮想マシンあるから、マシンが上がってくるの待つ辛さ無いかもね。 ロック処理についてちょっと相談です
●二つ以上のオブジェクトを同時にロックしたい
片側づつ順を追ってロックしていくのはダメ、デッドロックするので。
ロック出来ない状態である限り、ロックは限りなくしないようにしたい。
ロックに失敗までのタイムアウト処理もしたい。
●例えばこれだと、デッドロックを引き起こすので良くない
lock(obj1) lock(obj2) 処理;
●そこで、言語に以下のような構文があれば理想的なのだが
ないので、それらしいヘルパを作りたい、できれば効率的な物。
lock(obj1,obj2, ... ,timeout=1000) {
ロック成功の場合の処理
}
timeout {
タイムアウトした場合の処理
} ●とりあえず簡単に考えた、しかし無駄が多そうに見える、もっと良いものが欲しい。
DateTime begin = DateTime.Now;
再試行:
bool l1 = Monitor.TryEnter(obj1, 0);
bool l2 = Monitor.TryEnter(obj2, 0);
if (l1 && l2) {
goto ロック成功;
} else {
if(l1) Monitor.Exit(obj1); // チェックと共にロックしてしまうので、このコードも残念賞
if(l2) Monitor.Exit(obj2); // 同上
if ((DateTime.Now - begin).TotalMilliseconds > 1000) {
goto タイムアウト;
} else {
System.Threading.Thread.Sleep(10); // この待ち方も酷い
goto 再試行;
}
}
タイムアウト:
{
タイムアウト処理
}
ロック成功: ていうか普通にロック専用のオブジェクト作ってそれをロックすりゃいいんじゃねーの >>40
それだとロック粒度が大きくなりすぎて逆にデッドロックの可能性を拡大してしまいますね。 セマフォ使ったらどう?
資源数もタイムアウトもあるし >>42
セマフォは重いんですよねぇ
それをやるくらいなら>>39の例の方が効率的ですね。 >http://article.higlabo.com/ja/thread_locking.html
lock(Monitor.Enter/Monitor.Exit) 同じプロセス 20ns
Mutex 違うプロセスも可能 1000ns
SemaphoreSlim 同じプロセス 200ns
Semaphore 違うプロセスも可能 1000ns
ReaderWriterLockSlim 同じプロセス 40ns
ReaderWriterLock 同じプロセス 100ns
Semaphoreは高機能すぎて、あまり軽々しくは使えない。
そのわりにはlockと違ってスレッドチェックがないので自家中毒を起こしたりするので、別途そのための対処が必要になったりする。
lock 20nsはやはり捨てがたいものです。 >>45
そんな事は無いと思うんだけどな、セマフォに標準で実装されているように
これはマルチスレッドデザインパターンとしては基本になるかと。
というか教科書にある典型ですし。
ところが、Monitorにはなかったので、おや何故ない?となっている所。
せっかく高性能なのに有効活用できないのは勿体ないと。 >>47
分からないならレスしないでもらえますか?
流されては叶いません。 >>39
みたいなことをするぐらいならSpinLockを使った自前実装で処理したほうが良いかもしれない。
もしくは
>>lock(obj1) lock(obj2) 処理;
これでもデッドロックしないように、Lockする順番を厳格にしてコーディングするとか
というか、言葉遣いに気を付けたほうが良いと思うよ。 そんなにパフォーマンスが大事ならオプティミスティックロックも検討したら?
どうせ滅多に競合なんかしないでしょ >>48
そもそもロックが必要という判断に至った理由が明らかでない
ロックがベストな選択肢である保証はどこにもない >>49
ここにいる知らなくてもレスしないと死ぬ病気にかかっている奴はどうしょうもない。初心者の上にキチガイなら死ねって感じですが。
とりあえず、スピンロックは使いたくないですね、あれはCPUタイムをすり潰しながら高速動作を確保しようとするものだから
それの主用途は、激重計算タスクを並列処理するための物であって、目的とちょっと違いますね。
あと、排他処理をちゃんと勉強すると、順序等を考えていても意味が無くて
ロックする瞬間に作業に必要になるリソースをすべて確保して、必ず抜けられるという事の方がデッドロックに対する対処としては有用です。
でも、上に書かれているように一つのオブジェクトで粒度を上げてしまったら本末転倒になります。 >>51
ちゃんとわかっている人を待っているんだから黙ってろ アイデアを募るならもっと広い視野で考えたほうがいいってことでしょ
矮小な問題に限定されすぎていて、マイクロベンチマークレベルの不毛な議論にしかならない
状況によっては工夫すればロックフリーな実装もできるかもしれないよ >>52
https://www.jpcert.or.jp/java-rules/lck07-j.html
ソースはそれっぽいものを適当に引っ張ってきた
ロックする順序は意味あると思うんだけど、、、
デッドロックが怖いってことだと思うんだけどさ
親から子へ順番守ってロックすればデッドロックしないじゃん? >>55
世の中上には上の奴がいるんだよ、俺なんかよりはるかに知識を持っている奴はいくらでも。
お前より俺の方が知識あるが、そんな俺よりもはるかに凄いやつは山のようにいるんだ。
そろそろ、中二病みたいな全能感は捨てな >>56
親子関係があれば、親についている操作ようのメソッドにロック処理をいれれば問題ないですね。
でも、今回のは完全に独立しているオブジェクト間です。
ちょっと難しいですね。
実際問題としては、順序を使う側にすべて守らせるというのは、理屈では語れても実践的ではないかもしれません。
やはり、ロック時間を短くする事が肝要であり、その為には粒度を小さくするのが基本となるかと。
汎用的なやり方としては、この方法がもっとも優れていると思います。
なので、この方法をより高パフォーマンスで実現できるヘルパーを実装して纏めて利用したい訳です。
だから、別の方法は考えていないです。Monitorを使った高速排他処理が今回の最終目標です。 楽観的ロックのタイムアウトで、ロールバックするのが確実
人間には絶対にミス・バグがあるから、
デッドロックを100%、起こさないようにする事は、絶対に出来ないから >>59-60
だから、もう来るなって、お前には何も聞きたいことは無いし、そんな話は聞かされたところで新たな何かには全くつながらない。
C#スレには、初心者用じゃないもう一本の匿名ゴミすれあるだろ、そっちいけよ。
分かっている人が来たときにコメントがゴミだらけになる。 たぶん質問者の方が俺よりずっと詳しそうだから釈迦に説法だと思うけど、
>●例えばこれだと、デッドロックを引き起こすので良くない
>lock(obj1) lock(obj2) 処理;
これがデッドロックしうるのはこのスレッドがobj1だけをロックした状態で
別のスレッドがobj2をロックして、そのスレッドがobj1を待機してる場合だよね?
この場合このスレッドがobj1をアンロックしない限りobj2もアンロックされないからデッドロック
だから、ネストの内側のock(obj2) だけをタイムアウト付きのMonitor.TryEnterに置き換えれば
効率的かどうかはどうかはともかく、要件は満たせるんじゃいないの?
知らんけど >>62
まさにその通りです、それが直下に書いた雑な例です。
このヘルパーを作りたいという訳です、見るからに美しくないので詳しい人の登場をお待ちしているという所です。
必要な全ロック取得に失敗したら即座に全て解放して、乱数時間まって次を伺う。
これはよくある教科書通りです。 >>66
いいっすね、いいっすね
Thread.Sleep(100); ← ここがもうちょっとマシな待ち方になるといいんですがw
自分はインターフェイスは、IDispose使ってロック範囲を lock で書いたような雰囲気にしてます。
タイマーは、初ロック失敗の後にスタートさせて、ロック成功(大半のケース)でロスが少ないようにしてます。
なかなか素敵な感じになってくれませんw ↓のテンプレートとジェネリックの違い、にある
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/differences-between-cpp-templates-and-csharp-generics
トップ項目にある
・C# ジェネリック クラスでは、ユーザー定義演算子は呼び出すことができますが、算術演算子を呼び出すことはできません。
"算術演算子を呼び出すことはできません"ってどーいう意味っすか?
算術演算子って+-*/のこと? 遠まわしに制約について言ってるのかな。
算術演算子が使える型のみ受け入れるような制約はできないから
自動的に算術演算子は使えないことになるわけだけど... ジェネリックに算術演算子を使うなら、そんなに速度が要求されないんなら
(dynamic)にキャストしてからなら演算子が使える
まあこれキャッシュ付きのリフレクションだから速度は期待しないでよー C++ではテンプレートに焦点をあてた書籍はいくつかあるけど
C#でジェネリックに絞ったオススメ書物ってのはありますか?
C++のテンプレートテクニックのどれが使えないか?ってのは知りたい。 C#のジェネリックって1時間で読める記事で網羅されるぐらいの内容しかないっすよ すみません。ちょっと急いでいます。
C#でクラスを宣言する際に、
class {...} とpublic class {...}
このふたつの違いが判りません。
教えてください。 アクセス修飾子を省略したクラスは internal になる
public とか internal とかの意味については↓
アクセス修飾子 (C# プログラミング ガイド) | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers ありがとうごぜます。
internalですね。アセンブリ言語レベルの話のようなので
まだそこまで至ってないのでpublic, private, protectedだけ使います。
すみませんでした。 「アセンブリ」ってみて「アセンブリ言語」って理解するのは先が思いやられるな。全然意味が違う話なのに >>81
上記のページで「アセンブリ」と言ってるのはアセンブリ言語のことではなくて
「exe」とか「dll」とかのファイル単位での機械語のまとまりのことだよ ありがとう。
今自分でも調べていてなんか違うなーって思ってました。 今となっては、いや初めから忘れてもいい話だったけど
ファイル単位の物理的なまとまりはモジュール(.netmodule)で
モジュールをまとめた論理的まとまりがアセンブリ(.dll/.exe)
Visual Studioが2002の初めから一貫してサポートしてないこのモジュールって単位をMSはどう使うつもりだったんだろう 最終的に1つのライブラリにしたいものをC#とF#で部分ごとに書き分けるとかそういう例は見た事あるけど
(ものによってはF#のほうが書きやすいとか)
実際それが必要なユーザがどれだけいるのかって話な C++/CLIとC#の組み合わせがある。
最終的な呼び出し元はネイティブと同じ口なんだけど、
dynamicやasync/awaitなどを使いたいため、
dllexport付近の薄皮一枚だけ C++/CLI、
残りは全部C#で記述して1つの.dllにってのに.netmoduleを使う。
C#とF#の組み合わせとか、ほとんど無意味に思えるが… event解除ってnullぶっこんでもいいのかしら?
何処見ても-=でしろってのばかりで全解除の適切なやり方載ってないんだけど
一応null代入で動いてるぽいけどちと不安 まいなすはそれだけ消す、nullはすべて消す
できわるいコードだとnull入れると落ちるw 全解除ってそれなりに需要あると思うんだが何処も扱ってない不思議
+=って内から外へ処理出しする訳だから
インスタンスが破棄されたら当然破棄されるべきなのにどうもそうなってない
nullぶっこめばGC回収されるみたいだけど正しいやり方なのかな 購読側じゃなく発行側が勝手に解除ってのがちょっと...
むしろどういう場面で必要になるのか想像できないな
> +=って内から外へ処理出しする訳だから
> インスタンスが破棄されたら当然破棄されるべきなのにどうもそうなってない
ここは何を言ってるのかよく分からない
まあ、イベントというかデリゲートのマルキチャストの仕組みが分かりづらいのはわかる >>92
正しいというかとりあえず安全なのは何もしないの放り込んどく
それでも勝手に消されて困るのがあるかもしれんがw >>94
例えば非同期通信でデシリアライズ終わったらイベント投げて後は勝手に死ね、って場合
-=だと発行側で解除するのが困難でリークしちまう
最新VerC#ならTaskで後処理書けばいいけど、Unityだとつい最近まで3.5だったから >>96
俺の理解不足だったらごめん
リークするのはイベントの購読側のオブジェクトLがイベントの購読を解除しないまま
Lを参照する変数がなくなった場合で、発行側のオブジェクトPのイベントに
Lのメソッドが登録されたままPへの参照がなくなってもそれはリークにならないと思うんですが >>97
そう思ってた時期が俺にもありました
しかし実際はリークしてOutofMemoryが出る
どうも購読側参照が残ってると到達可能と見られてGC回収されないぽい
本当にそういう理屈かは知らんけどnullぶち込むと例外でなくなる >>98
>どうも購読側参照が残ってると到達可能と見られてGC回収されないぽい
登録解除してないから購読側は発行側から参照されてて回収されない
その状態で購読側が発行側を参照してるんなら発行側も回収されないよね 循環参照しててもルートから到達不能なら回収されるよ
されないなら単に循環参照以外の参照が何かしら残ってるだけ
いいや解放されないね!とかいう思い込みに付き合う気はないから
口ごたえがしたければ、VSのメモリーアナライザーで
リークしているというオブジェクトの参照状態のスナップショットを撮って
ここに貼り付けてから続けるように >>101
すまんすまん、他の言語と勘違いしてた。 WebBrowserコントロールを使うと、レジストリ編集しないと自動的にIE7相当になってしまうんですが、
レジストリ編集無しでIE11相当にするにはどうしたらいいでしょうか?
もしくは、dllファイル1つで済むなら、他のブラウザコンポーネントでもいいです。 IEは他にはhtmlのmeta要素使うとか
レジストリっていってもHKCUなんだからアプリ起動時に書き込むだけのことだけど >>103
CefSharpっていうChromiumの実装がNuGetにあるよ
AnyCPUに対応してないんで導入が若干手間だけど気合いでがんばれ >>103
CoInternetSetFeatureEnabled #EntityFrameworkの質問ってここでよいですか?
EFCore+Sqliteで開発してるんですが、".db"ファイルのパス指定で困ってます。
コネクション作成時に、以下でdbパス指定をしています。
var connectionString = new SqliteConnectionStringBuilder { DataSource = @"./app.db" }.ToString();
この場合、理由がよく分かってないのですが、
Update-Databaseを実行した時(CreateDatabaseが発行される時)、プロジェクトフォルダからの相対パスになり、
SaveChangesを実行した時(Insert文が発行される時)、/bin/debugからの相対パスになります。
毎回相対パス指定を変えるのが面倒で、かつ絶対パス指定はしたくないもので。
何か良い方法はありませんでしょうか。 俺ならexeパス取得して絶対パス作ってそれ使うけど、
絶対パスいやならカレントフォルダ変更したら? >>109
プロジェクトフォルダにできます。
ただ、プログラム実行時は別のパス見てるからDBないエラーになります。
>>110
あー、それいいかもです。
やってみます。 個々の人ってWinFormとWPFどっちで作ってる? 新規は基本的にWPFだけど、使い捨てのツールはFormsのことも多い。 昔はVSが何かっつと即堕ちして使いもんにならんかったが
今はまともになったんかねWPF WPFって技術資料があんまないから、つっかかりにくいんだよなあ >>119
あれだ外人からみれば
そうみえんじゃねw つっかかりにくい→つかえやすいorつっかえやすい
それとも
つっかかりにくい→とりつきにくいorとっつきにくい
あんまない→あまりないorあんまりない ■ このスレッドは過去ログ倉庫に格納されています