- PR -

C# File.Delete()が遅れる

投稿者投稿内容
TAKA
会議室デビュー日: 2006/01/06
投稿数: 3
投稿日時: 2006-01-06 22:12
初めて投稿させて頂きます、TAKAと申します。

現在、OS:Windows2000、.NET 2003の環境で開発を行っています。

そこで皆さんのお知恵をお借りしたいのですが・・・。

表題のように、File.Delete()が遅れます。
やっている内容としては、動画を表示し、そのFileを消す、というものです。
Codeは拝借したものですが、どこから使わせて頂いたものか、他の者が行った
のでわかりません・・・、すみません。CodeProjectだったらしいのですが。

下の _deleteFile関数を呼んだ際、Exceptionが出ずに終了します。別の処理時、
DoEventsなどを呼んだ際に対象 Fileが削除されることはわかったのですが、
_deleteFile関数の中で DoEventsを呼んでも削除されません。 FilgraphManager
には Disposeも Closeも何も無く、さてどうしたものかと悩んでおります。

ささいなことでも構いませんので、お気付きの点がありましたらご教授ください。

----------------------------------
private void _openAVI(String fileFullName)
{
_objFilterGraph = new FilgraphManager();
_objFilterGraph.RenderFile(fileFullName);

_objBasicAudio = _objFilterGraph as IBasicAudio;
_objVideoWindow = _objFilterGraph as IVideoWindow;
_objVideoWindow.Owner = (int) _pnlMovie.Handle;
_objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
_objVideoWindow.MessageDrain = (int) _pnlMovie.Handle;

_objMediaEvent = _objFilterGraph as IMediaEvent;
_objMediaEventEx = _objFilterGraph as IMediaEventEx;
_objMediaEventEx.SetNotifyWindow((int) this.Handle,WM_GRAPHNOTIFY, 0);

_objMediaPosition = _objFilterGraph as IMediaPosition;
_objMediaControl = _objFilterGraph as IMediaControl;
_objIBasicVideo = _objFilterGraph as IBasicVideo;

_objVideoWindow.SetWindowPosition( 100, 100, 200, 200);
_objMediaControl.Run();
_CurrentMovieStatus = MediaStatus.Running;
_objMediaControl.Pause();
_CurrentMovieStatus = MediaStatus.Paused;
_objMediaPosition.CurrentPosition = 0;
}

private void _deleteFile( string path )
{
try
{
if( File.Exists( path ) )
{
File.Delete( _fiMPG.FullName );
}
}
catch( Exception e )
{
MessageBox.Show( e.ToString());
}
}
sia
常連さん
会議室デビュー日: 2004/05/02
投稿数: 38
投稿日時: 2006-01-06 22:46
どうもです。

FilgraphManager は使ったこと無いですが、COMオブジェクトですよね?
Marshal::ReleaseComObject
でCOMの参照を消したらどうなりますか?
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2006-01-06 23:06
諸農です。

引用:

表題のように、File.Delete()が遅れます。
やっている内容としては、動画を表示し、そのFileを消す、というものです。



遅れるというのはどういう意味でしょうか?
最終的にはファイルは目的通りに消えると言うことですか?
それとも消えないのですか?
消えない場合、何が問題なのでしょうか?


引用:

Codeは拝借したものですが、どこから使わせて頂いたものか、他の者が行った
のでわかりません・・・、すみません。CodeProjectだったらしいのですが。



なぜそのコードを選択したのか。。と問い質したくなりますね。
ところで、Stop()で止めてからFileInfo.Delete()で消したらダメですか。ファイル使用中であれば例外も出そうですし。
COMなのでReleaseなんとかで解放できそうな気もしますけど。。
すみません、なんというメソッドかは調べてくださいませ。

引用:

下の _deleteFile関数を呼んだ際、Exceptionが出ずに終了します。別の処理時、


呼び出している箇所を見つけることが出来ませんでしたが、
別のところからの呼び出しですか?
また、例外が出ないことに何か想定外の問題があるのですか?

全体的に、何が問題点なのかが把握できませんでした。



_________________
諸農和岳
Powered by Borland Delphi/C++Builder & Microsoft VS.NET

[ メッセージ編集済み 編集者: Jubei 編集日時 2006-01-06 23:07 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-07 00:11
不必要なことで COM を扱って欲しくないと願っている 1 人です。
.NET なのですから CLR を使いましょう。
作りこみを直すにしてもすぐ解決する問題ですし、保守のことも考えてみてください。

COM を扱うということはこういうことです。

  COM オブジェクトを解放する

イヤになりませんか? (^^;)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
TAKA
会議室デビュー日: 2006/01/06
投稿数: 3
投稿日時: 2006-01-08 01:20
siaさん、Jubeiさん、じゃんぬねっとさん、ご教授ありがとうございます!

まさに COM Objectで、Marshal.ReleaseComObjectを使ってみます。
で、私もあまり COMを使いたいと思っていないので、CLR(まだ勉強不足で知りませんでした)を使ってみたいと思います。

Jubeiさん、deleteは別のところで呼んでいます。挙動が違うかもしれないと思い、File.Delete()とFileInfoの Delete()を使ってみましたが、そのタイミングで消されるわけではないようです。たぶんsiaさん、じゃんぬねっとさんの言うようにそのタイミングでは開放されれないため、ある別のタイミングで開放されて削除が実行されたんだと思います。

みなさんありがとうございました!
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-01-08 02:39
COM や CLR は良く知りませんが、Delete の類のメソッドは即時に実行されるものではないでしょうか?Delete が遅延実行されるということは、あまりないような気がします。
引用:

TAKAさんの書き込み (2006-01-06 22:12) より:
if( File.Exists( path ) )
{
File.Delete( _fiMPG.FullName );
}


もしかしたら、この個所で Exists が false になっていて Delete がそもそも実行されなくて、コードの別のところで後で別途 Delete しているということはないですか?
上記の Delete の直前、直後にデバッグ用のメッセージ出力を入れたり、さらにはそこで、ファイルの存在を検査してみてはどうでしょうか。

と、書いてから気づいたのですが、上記の Exists と Delete の引数が異なっている(path と _fiMPG.FullName)のですが、これで大丈夫ですか?
こういう場面では、普通は引数に同じ変数を指定するはずです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-08 10:15
引用:

unibonさんの書き込み (2006-01-08 02:39) より:

COM や CLR は良く知りませんが、Delete の類のメソッドは即時に実行されるものではないでしょうか?
Delete が遅延実行されるということは、あまりないような気がします。


しっかり見ていませんでしたが、正しくそうですね。
System.IO.File クラスの Static なメンバはすべてスレッド セーフですし、
何らかの原因で Busy 状態であっても、削除されるまで制御が移ることはありません。

今、読み返してみて、本当に Delete を通っているかどうか疑問に感じたところは、

引用:

下の _deleteFile関数を呼んだ際、Exceptionが出ずに終了します。


ここです。

この確認方法では、デバッグ実施した結果としての信頼が不足します。
System.IO.File.Delete メソッドはファイルが存在しない場合でも、例外は発生しない仕様になっています。

引数のパスを削除しているわけではないという点はかなり疑わしいです。

# これ、メソッドとして Extract している意味がないですね。(しかも、誤解される名前で)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
TAKA
会議室デビュー日: 2006/01/06
投稿数: 3
投稿日時: 2006-01-08 15:45
書き込みありがとうございます。

Deleteメソッドは基本的には即時実行されるものだと思っていましたが、COMでの処理のせいか、Instanceが生きている場合、実行されないようです。恐らく、ですが、WindowsMessageでその処理を行っていると思われます。C++なら簡単に確かめることができるんですが…。
ともかく、Existはしています。それは間違いありません。(常にExplorerで確認していますし) 提示したコードが悪かったですね、すみません。

上記の理由が正しいかどうかはわかりませんが、以下の現象が発生します。

1.Delete()を呼び、UserI/Fに処理が帰ってくるまで待つ (この時点で、Fileは削除されない)。Applicationを終了させる(このタイミングで削除される)。

2.Delete()を呼び、UserI/Fに処理が帰ってくるまで待つ(この時点で、Fileは削除されない)。DoEvents処理を含む処理を行う(DoEvents()の行の処理を行った時点で削除される。)。

面白いことに、あるFileに対して最初の Delete()を呼んだ場合、Exceptionは発生しませんが、2度目を呼んだ場合エラーが出ます。内容としては ”誰かがアクセスしているので出来ません”と出ます。正しいエラー内容は、いまわからないのですが、また火曜日に投稿します。

ちなみに、_deleteFilesは、実際には別の Parameterの処理も行っています。FileI/Oに関係ないところは削除しています。

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