ふらっと C#,C♯,C#(初心者用) Part134
■ このスレッドは過去ログ倉庫に格納されています
「どんなにくだらないC#プログラミングやVisual C#の使い方に関する質問でも誰かが優しくレスをしてくれるスレッド」です。
他のスレッドでは書き込めないような低レベルな質問、
質問者自身なんだか意味がよく分からない質問、
ググろうにもキーワードが分からないなど、勇気をもって書き込んでください。
内容に応じて他スレ・他板へ行くことを勧められることがあります。ご了承下さい。
なお、テンプレが読めない回答者、議論をしたいだけの人は邪魔なので後述のC#相談室に移動して下さい。
C#に関係の無い話題や荒らしの相手や罵倒レスはやめてください
>>980を踏んだ人は新スレを建てて下さい。
>>980が無理な場合、話し合って新スレを建てる人を決めて下さい。
■前スレ
ふらっと C#,C♯,C#(初心者用) Part133
http://mevius.5ch.net/test/read.cgi/tech/1510056685/
■関連スレ
C#, C♯, C#相談室 Part95
http://mevius.5ch.net/test/read.cgi/tech/1508180530/
C#, C♯, C#相談室 Part93
https://mevius.5ch.net/test/read.cgi/tech/1492818720/
■コードを貼る場合は↓を使いましょう。
http://ideone.com/
https://dotnetfiddle.net/
■情報源
https://msdn.microsoft.com/ja-jp/library/gg145045.aspx
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/index
https://msdn.microsoft.com/en-us/library/gg145045.aspx
http://referencesource.microsoft.com/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured >>24
例えばテスト対象のメソッドが何らかのAPI呼び出してるとして、そのAPIがエラーを返すケースのテストをする時にスタブを使ってエラーを返したりする >>24
テストしてて、ここ触りたくねえなあデータ用意すんの面倒臭えなあと思うことあるだろ?
正しいかどうかは別にして、とりあえず臭いものに蓋をしたまま手っ取り早くテストを終わったことにして帰宅できる >>26
>>27
>>28
ありがとう
そしてC#じゃない話広げてごめん
テストの為にSQLだったりなんか色々条件準備するの大変だからスタブで置き換えちゃおうみたいな感覚なのかな >>30
大変だからというか、テスト目的と関係ないAPIやDBアクセスに依存しないようにするため こういう奴らってサーバーがAWSとかGAEのサーバーが503で落ちてる時のテストとかどうやってんの?
DoS掛けて落としてるの? サーバーが落ちてる状態をスタブ/モックで再現すればいいんちゃう? プログラミング始めたてなんだけど、CSVファイルの先頭何行を無視してそれ以外のデータをデータベースに入れたいって状況になったんだけど、経験者の人はめっちゃ簡単だよって言ってて、
でも俺には全く想像もつかなくて、プログラミング出来る人の頭の中はほんとどうなってるんだ…
やっぱみんなもこれくらいのコード書くのは楽勝なの? >>37
一瞬でアルゴ思いつくけど、おまえやばくね? >>38
やっぱ経験者からすると簡単なんだ
すげぇなぁ…
CSVなんて触った事ないしそこから先頭何行とか全く想像もつかん
始めて数ヶ月だけどオレ向いてないんだろなぁ >>37
テキストの数行をスキップするのならすぐできるだろ。それがCSVになるだけ
CSVのパーサーについては
https://dobon.net/vb/dotnet/file/readcsvfile.html
にいくつもやり方が乗っている
ネットで調べればC#初心者でもできる案件 いっぺんに全部やろうとするんじゃなくて、小さい作業に分解して考えるんだよ
今回なら「先頭数行を無視してテキストファイル読み込む」にCSVは関係ないでしょ?まず欲しい分だけ読み込んで、CSVとしてパースするのはその後に考えればいい
ググって出てくるくらいまで分解すれば、あとは組み合わせておしまい >>41
>今回なら「先頭数行を無視してテキストファイル読み込む」
要素内に改行がある場合(めったにないが)を想定しなきゃならないので先にパーサーを通す必要がある
元の要件が「CSVファイルの先頭何行を無視して」だから >>42
この場合、先頭数行はヘッダーでcsvじゃないのでは まずは
・CSV の先頭になんかワケわからん行がくっついてる
のか
・CSV のデータを何件か読み飛ばす
のかをはっきりしろって話だわな どうせ読み飛ばすんだからどっちでもええやろそんなもんw ここ数日ここ見てたんだが自称上級者様がドヤ顔してるだけのスレだな >>47
どんなのが理想なんだ?
ぶっちゃけほとんどの質問に回答がもらえてるようだが 会計システムはクラサバが最低限の要件なので、計算はDBでやるからクラス分けなど何の役にも立たないし却って邪魔だ
彼はクラサバと無縁なスタンドアローンの世界に住んでいるのかもしれんね スタンドアロンだとして、どういうデータ設計したら費用項目ごとにクラスができるんだろうね
日付, 費用種別コード, 金額
まさかこんなタプルで管理してるんだろうか そ、ギョーミーな戦場ではオブジェクト指向などと言う玩具の武器は役に立たない 何をいっておる、LinqもLambdaも戦場の小火器として使えるが腐ったオブジェクト指向など使えぬわ 腐ったオブジェクト指向脳で単純なものを複雑にするヤツが大嫌いなだけ 結局個人的感情か
毎回レスの最後に ※個人の感想です って付けとけよ >>59
全レスそうだから省略できる
もちろん個人の感想だが 大きなスケール→ガチガチのオブジェクト指向
小さなスケール→手続き型、関数型 名前、住所、電話番号、みたいなデータがあったとして、
Aさんの住所を参照するのに、["A"]的なアクセスするやつ、なかったでしたっけ? ボタンを押すと処理を緊急停止するプログラムを作りたいのですがどのような方法がありますでしょうか? >>68
とりあえずthis.Close()でFormを閉じる
それでだめなら要件を挙げて 今はbackgroundWorkerで処理を実行しているのですが
CancelAsync()で停止させても
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
というコードに到達するまで停止しないので停止までに時間があるのを改善したいです
このコードをたくさん差し込むしかないのでしょうか? >>70
親フォームでkillしたらbackgroundWorkerも止まるんじゃないの? どういうことでしょう
あらゆる処理をForm1に書いていまして
killの仕方がわからないです backgroundWorker以外の処理は生かしておきたいって話なら分からないな
>>70
というかキャンセル用のフラグ作って止めなきゃならないところに停止処理差し込むのがそんな大変だとも思えないけど
楽したいってのはわかるけど、それは他の人に聞いて >このコードをたくさん差し込むしかないのでしょうか?
>あらゆる処理をForm1に書いていまして
まず、設計の仕方を覚えた方が良い 自作プログラムでSemaphoreFullExceptionが発生したんだけど、これってSemaphore使って無くてもTaskやawait使っていれば発生するようなもんなの? >>77
Unhandledで拾ったは良いものの、例外詳細見たらスタックトレースに他の発生行が無くてその例外行だけだったのよ
どこかでthrowし直してたとしてもその行が表示されるのにな >>70
なんか先週ぐらいも同じ質問してた人がいたけどw
だからさあ、メソッドを外から強制的に止めようって発想が間違ってる。
メソッド自身が何かをポーリングして自分で止まるように作る backgroundworkerとtaskの違いは何よ? >>81
ここで2回も聞くぐらいなら
やりたいことを英語にしてGoogleで検索した方がいいよ
ここにいる人が知らないか教えないだけで
やり方はちゃんとある
ポーリングとか今どきダサすぎるからやめとけ いやいやないからアホかw
あるなら言ってみ。まあ無理せんでよろしい。
生スレッドは強制終了できるが普通は推奨されない。 そもそも外から強制的に止めるって発想に疑問を持たない時点でセンスがない >>88
スレッドの強制停止は推奨されないから、事実上ポーリング的な手法しか無いと思うけど。
(マルチプロセスは考えないとして) CancellationToken.ThrowIfCancellationRequested()使うけど、これもポーリングだしな。 >>88
つか、今標準のCancellationTokenもポーリングが基本だよ
そっから抜け出るのに例外使うのがミソではあるが スリープで時間かかってたり繰り返しスリープ入れてるなら
Interruptを使って無理矢理中断させることもできる >>70
Async が付いている関数は、非同期処理だから、コンテキストが異なる。
だから、処理が実行される順番が確定しない
Sync なら同期処理だから、順番が1つに決まる。
つまり、ソースコードの上から下へ、順に実行される
コンテキストが異なるもの同士が通信するには、プロセス間通信(IPC)を使う。
基本的には、相手のキューに、投入することしかできない
1. 依頼する。A プロセス → OS → B プロセス
2. B が届いたメッセージを処理する
3. 返事する。B プロセス → OS → A プロセス
これを同期処理にすると、1〜3 の処理中、
アプリが止まる(ストール)から、GUI では嫌われる。
50ms 以上掛かる処理は、非同期処理にすべき
逆に、CUI では同期処理にして、コンソールが止まる このどことなくズレたレスをつける句読点過剰くんってのは、やはり糖質なのだろうか? 句読点箇条君はすぐわかるな
そして必ず間違ってる
スレッドが違うだけならIPCなんか使う必要ない
普通は単にメモリを共有する
FormsのBeginInvokeなどで使われているSynchronizationContextのキューも普通にメモリを共有してるだけだ つまり、1〜3 は、OS が行っている事だから、何もできる事が無い。
OS レスのマイコンとかなら、自分でプログラミングするけど
何かをしようとしても、OS がCPU のタイムスライス、
プロセスの優先度・実行順番を決めているから、何もできない
それがOS。
OSレスなら、それらを自分でプログラミングしないといけないから、無理 このアスペは>>97も理解してないんだと思うけど、初心者スレだから改めて否定しておく
スレッドが違うだけなら、>>95の123は正しくはこう
1. スレッドAがジョブの情報Jをメモリ上のキューQに登録する
2. スレッドBはQからJを取り出し、Jの内容に従って処理を実行する
3. Bは処理結果RをキューQ'に登録する
4. AはQ'からRを取り出し、後続処理を実行する
AとBの間で普通にQやQ'を直接共有してるだけで、OSなんか全く関係ない
そもそもマルチスレッドに限った話でもなく、例えば、ゲーム内で2つのキャラクターの間でやり取りしたい、
でも直接メソッドを呼ぶと長くなるとか、間にウェイトを入れたいとかで一旦処理をゲームループに戻したい、なんて時にも使える オレオレキューなんぞつかわずにTaskを使え
バックグラウンドといえどインプロセスで長大な処理を発生させるな
そういうのはジョブ管理サービスを使えHangfireとかな 今回はTaskかどうかは問題ではなく
「BackgroundWorkerの処理を中断する方法で、ポーリングより面倒くさくない方法があったら教えて」
なので
Thread.Abortでも使え Task大好きッ子もなかなかスレの流れ読んでねえよな asyncつけてるとエラー発生したらデバッグの実行位置の矢印の動きがおかしくなる RunWorkerCompletedでイベントオブジェクトのフラグをいじり、それを待機とかだめ? Task関連は7標準のランタイムだと使えないからいまだにBackgroundWorker使ってる
まあ他ソフトの事情で.NET 4以降一切入れないってことはないんだけどさ 自分のBackgroundWorker使ってるソース見てみると、
処理単位でループして1処理終った後と、長い処理の途中でwk.CancellationPending == trueで抜けるか判定してる
イベント待ちはタイムアウト設定して一旦抜ける
という感じだった
Task使っても同じだろう @Abortはしたくない
Aメインループのフラグチェックでは頻度が足りない
Bでもフラグチェック処理を書き足すのは嫌だ
要件はこれでいいか?
真面目に考えるとメタプログラミングの領域だな
チェック頻度とパフォーマンスのトレードオフも考えなきゃならん
初心者スレ民の実力では難しいんじゃないか? >>107
この頻度が足りないって、メインループの記述が冗長とか別の理由ありそうな気がするわ クッソ長いループ書いてんだろうな
マルチスレッドより先に基本的なコード整理術を覚えたほうがいい たくさんレスありがとうございます。
わからない言葉がたくさんあるので調べてまた来ます。 キーボードをa,b,c,dと順番に5秒置きに押していくメソッドをBackgroundWorker内で無限ループさせていて
キャンセルボタンを押したときすぐに止まって欲しいのですが必ずdまで押されてから止まるので困っているという感じです
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
play_abcd();
if (backgroundWorker1.CancellationPending)
{
// イベントをキャンセルする
e.Cancel = true;
return;
}
}
} キーボードをa,b,c,dと順番に5秒置きに押していってすぐ途中で止められるプログラムを作るには
どういう方法があるんでしょうか?BackgroundWorkerにはこだわりません。
play_abcd()メソッドには押したボタンをtextBoxに表示する機能もあってBackgroundWorkerを使うと
プログラム実行中でもきちんと表示されるのでBackgroundWorkerを使っています private IEnumerable<Action> GetJobs(int sleepMilliseconds) {
/**/var buttons = new [] { btnA, btnB, btnC, btnD };
/**/while (true) {
/**//**/foreach (var button in buttons) {
/**//**//**/yield return () => button.Click();
/**//**//**/yield return () => Thread.Sleep(sleepMilliseconds);
/**//**/}
/**/}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
/**/while (true) {
/**//**/foreach (var job in GetJobs()) {
/**//**//**/job();
/**//**//**/if (backgroundWorker1.CancellationPending) {
/**//**//**//**/e.Cancel = true;
/**//**//**//**/return;
/**//**//**/}
/**//**/}
/**/}
} play_aとplay_bとplay_cとplay_dを分ける
デリゲート配列にしてforeachで回せばチェックは一カ所で済む BackgroundWorkerじゃなくてタイマー使うべきだよ >>111
>>113
>play_abcd()メソッドには押したボタンをtextBoxに表示する機能もあって
ってことはたぶんplay_abcdの中でbackgroundWorker1.ReportProgressを呼んでいる、
つまりbackgroundWorker1を参照できる場所にplay_abcdはあるんだから、
素直にCancellationPendingをポーリングするだけじゃないの?
本当はよくないと思うけどねこういうの
本当は前も書いたみたいにplay_abcdのシグネチャを
void play_abcd(Func<bool> canceled){...}
とかにして、呼び出すときに、
play_abcd(() => backgroundWorker1.CancellationPending);
がいいと思う
っていうか、そもそも
>キーボードをa,b,c,dと順番に5秒置きに押していくメソッド
をビジーループで実弁する必要本当にある?w
それ、タイマーで十分実現できると思うんだけど... BackgroundWorkerのほうが実装が綺麗になるよね >>117
スペース2つで改行だっけ?
普通のレスの書き方と分離するためにコマンドを先頭に付けるとかかな
専ブラが対応すれば専ブラだけでは見れるな タイマーなら、キャンセルでタイマー止めればそれで終わりでしょ
実装が見苦しいようには見えんね ■ このスレッドは過去ログ倉庫に格納されています