- PR -

高負荷時のテキストファイル書き込みで例外が発生する

投稿者投稿内容
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-02 09:59
引用:

nanbuさんの書き込み (2006-02-02 02:10) より:

これは、C++/CLIに関してのみですよね?


私も勉強の身ですが、そのはずです。

確かに C++/CLI はファイナライザとデストラクタが共存されます。
スコープを抜けた時点でデストラクタによって Dispose が呼び出され、そのうち GC によって回収されます。
リソースが回収されたタイミングがファイナライザになります。
このように、using 構文を必要としないという特長があります。

ただし、これは、

コード:

    Form1 f;


のような宣言をした時だけです。
gcnew パターンは以下のようになります。

コード:

    Form1^ f = gcnew Form1();
    delete f;


一概に「C++/CLI はこうだ」とは言えないわけですね。

余談ばかりが続きましたが、(^^)
最初に書きましたデストラクタ パターンは、C# らには現在のところないですので、

引用:

C#はもともとusingステートメントによって確定的破棄ができて、
これは、2.0でも同じ方向性である認識です。


これはおっしゃるとおりになると思います。
C# や VB などは明示的な構文が必要です。

# とか書いていたら、C++/CLI 専用スレが欲しくなってきました。
# 脱線していくのも何ですし、せっかくのネタを潰すのも惜しいので別スレでやりたいなぁ。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-02-02 11:54
いわゆる「高負荷時」に良く発生するエラーの多くは、マルチスレッド絡みのバグが多いですが、ダメモトで、ためしにたとえばマルチ CPU を使ってたらシングル CPU にするとか、HT(Hyper Threading)がオンになっていたらオフにするとか、を試してみてはどうでしょうか。そんな面倒なことをせずとも、タスクマネージャーでも指定できたと思います。
(もっとも、マルチスレッド絡みのバグが原因で「高負荷時」にエラー発生するのであって、逆がかならずしも成り立つわけではありませんが。)
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-02-02 21:20
引用:

yaさんの書き込み(2006-02-01 23:21)より:

私もそう思いますが、弾くんではなく調停(同時にアクセスしない&安全に待つ)を望んでいるでしょうからMutex使うのはありだと踏みます。


 ごめんなさい、言葉を誤りました。
 確かに、“待つ”必要がありますね。で、引数3つのコンストラクタを使っているので、そのとおりでしょう。
 ところで、これで作っても、所有者になれなかったからといってその場で待ってはくれないですよね。同じように、FileShare を使っても待ってくれないのは一緒なので、“待つ”という処理は自分でコーディングしていると思います。それならば、Mutex というアンマネージドなリソースを別に作るのではなく、ファイルだけで済ます方が安くつくのでは?と、思いました。


 それで、私は過去にどうしたのかなぁ?と思ってコードをほじくると、 System.Threading.ReaderWriterLock を使っていました。こいつだと、1プロセス内に限られますが、待ってくれますから。

〆 written by Jitta on 2006/02/02
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2006-02-02 23:37
引用:


ところで、これで作っても、所有者になれなかったからといってその場で待ってはくれないですよね。同じように、FileShare を使っても待ってくれないのは一緒なので、“待つ”という処理は自分でコーディングしていると思います。それならば、Mutex というアンマネージドなリソースを別に作るのではなく、ファイルだけで済ます方が安くつくのでは?と、思いました。



ん?取得できなかったらWaitOneをして待つんではないのですか?

コード:

class Program {
static void Main(string[] args) {
bool has;
using(Mutex mutex = new Mutex(true, "MyMutex", out has)) {
if(has || mutex.WaitOne()) {
Console.WriteLine("Press Any Key...");
Console.Read();
mutex.ReleaseMutex();
}
}
}
}



こんな感じで。あ、名前にGlobalつけてませんので新らしめの環境ではつけるコードを入れてくださいね。

# 以下追記

引用:


これは、C++/CLIに関してのみですよね?
C#はもともとusingステートメントによって確定的破棄ができて、
これは、2.0でも同じ方向性である認識です。



うーん、いいたいことは1.1は「アンマネージリソースの破棄のみとしてのIDisposableだったが、2.0でそれだけではない方向も含みつつあるよ、ということなのです。「汎用のデストラクション」と私は言いましたが、重要なのはデストラクションの部分ではなく汎用のという部分で、つまり意味が広がっているよということです。
C++/CLIのデストラクタの例は、「そのように実装される可能性があがる仕様だよね」って言う話であって、あまり強い例ではありません。むしろ注目してほしかったのは、実際に利用している例のTransactionScopeです。


コード:

using(TransactionScope scope = new TransactionScope())
using(SqlConnection conn = new SqlConnection(@"..."))
using(SqlCommand cmd = new SqlCommand(@"...", conn)) {
conn.Open();
cmd.ExecuteNonQuery();

scope.Complete();
}



一番簡単な例ですが、TransactionScopeは「アンマネージリソースを破棄」するのではありません。動作は「Disposeが呼ばれたときにCompleteが呼び出されていればコミット、そうでなければロールバックを行う」という動作になります。この動作によって「例外が途中で発生した場合、ロールバックを行う」という動作が行われるようになります。
この使用法はいってしまえばスコープのマーキングです。このように、もっと汎用的な確定的処理も考慮に入れるべきであるという話です。


[ メッセージ編集済み 編集者: ya 編集日時 2006-02-02 23:52 ]

[ メッセージ編集済み 編集者: ya 編集日時 2006-02-02 23:55 ]

[ メッセージ編集済み 編集者: ya 編集日時 2006-02-03 00:35 ]
nanbu
大ベテラン
会議室デビュー日: 2004/08/19
投稿数: 178
投稿日時: 2006-02-03 04:52
引用:

yaさんの書き込み (2006-02-02 23:37) より:

うーん、いいたいことは1.1は「アンマネージリソースの破棄のみとしてのIDisposableだったが、2.0でそれだけではない方向も含みつつあるよ、ということなのです。「汎用のデストラクション」と私は言いましたが、重要なのはデストラクションの部分ではなく汎用のという部分で、つまり意味が広がっているよということです。


うーん、「破棄」の流れで「汎用の確定的デストラクション」っていう言い回しで
「汎用」が重要って、、、日本語むずい。
「Disposeメソッドの実装がアンマネージリソースの解放のみではない」ということで意味が広がったというのなら、既に広がっていたのでは?
私はDisposeメソッド内でイベントハンドラの削除とかやってましたし(カスタムデザイナで)。

引用:

一番簡単な例ですが、TransactionScopeは「アンマネージリソースを破棄」するのではありません。動作は「Disposeが呼ばれたときにCompleteが呼び出されていればコミット、そうでなければロールバックを行う」という動作になります。この動作によって「例外が途中で発生した場合、ロールバックを行う」という動作が行われるようになります。
この使用法はいってしまえばスコープのマーキングです。このように、もっと汎用的な確定的処理も考慮に入れるべきであるという話です。


結局クリーンアップ処理でしょ。
1.必要であれば保持しているコンポーネントのDisposeを実行する。
2.アンマネージリソースがあればこれを破棄する。
3.Disposedな状態にする。
この骨組みにTrasactionScopeとしてのクリーンアップ処理が加わっただけで、
意味的に変わっている気がしませんが、、
そんな単純じゃないのかな?

スキルアップ/キャリアアップ(JOB@IT)