マクロで「FindInFiles」を別ウィンドウで実行させるとハングする
-
環境:Windows11(x64) Version 25H2 / Mery(x64) Version 3.8.9
現在メインとサブの2つのエディタウィンドウを使い分けており、メインのウィンドウで開いているファイルの文字列をGREPしてサブのウィンドウに出力したいと思い、次のようなマクロを組みました
var SubEditor = Editors.Item(Editors.Count - 1); SubEditor.NewFile(); SubEditor.FindInFiles("検索文字列", Document.Path, meFindRecursive); Document.Activate();しかし、実行すると高確率でハング?するようです。
マクロは最後まで実行されているように見えますが、マクロメニューが「停止」以外グレーアウトしており、「停止」を選択しても停止しない状態となります。なお、サブのウィンドウで開いたファイルで実行した場合はこの現象は起こりません。
FindInFiles行をコメントアウトするとハングしないので、現行ウィンドウ以外でFindInFilesを呼び出すと想定外の何かしらが起こるのではないかと考えています。
| euclid | 返信 -
ご報告ありがとうございます。
いただいた条件で検証してみたのですが、こちらの環境では現象を再現できませんでした。
もう少し詳しく状況を確認したいため、いくつか教えていただけますでしょうか。
> 現在メインとサブの2つのエディタウィンドウを使い分けており、メインのウィンドウで開いているファイルの文字列をGREPしてサブのウィンドウに出力したいと思い、次のようなマクロを組みました
ここでいう「エディタウィンドウ」というのは、タブのことでしょうか?
それとも、[ウィンドウ] → [タブを有効にする] をオフにして、SDI モード (タブではなく個別のウィンドウが開くモード) で使用されているということでしょうか?
また、ハングするタイミングについても教えていただけると助かります。
- [ファイルから検索] の途中でキャンセルした場合に発生する
- [ファイルから検索] が完了しても、マクロ側に処理が戻ってこない
- 検索自体は完了しているように見えるが、Mery を操作できなくなる
など、どのような状態になるのか分かると、原因を絞り込みやすくなります。
なお、GREP は v3.6.0 以降、マルチスレッドで動作するようになっています。
そのため、検索対象に巨大なファイルが含まれている場合など、検索スレッドの終了待ちが影響している可能性も考えられます。
たとえば、巨大なファイルの検索中にキャンセルした場合、検索処理が終了するまでは一時的に Mery が応答しなくなることがあります。
こちらでも引き続き検証しますので、使用されている設定や検索パス、検索対象に巨大なファイルが含まれているかどうかなど、お気づきの点がありましたら教えていただけると、問題解決の糸口になるかもしれません。
よろしくお願いいたします。
| Kuro | 返信 -
> ここでいう「エディタウィンドウ」というのは、タブのことでしょうか?
>
> それとも、[ウィンドウ] → [タブを有効にする] をオフにして、SDI モード (タブではなく個別のウィンドウが開くモード) で使用されているということでしょうか?
タブが有効の状態で、タブをウィンドウ外にドラッグすると新たにウィンドウが立ち上がると思いますが、それでできた新しいウィンドウを「サブのウィンドウ」と表現しています。> また、ハングするタイミングについても教えていただけると助かります。
>
> - [ファイルから検索] の途中でキャンセルした場合に発生する
> - [ファイルから検索] が完了しても、マクロ側に処理が戻ってこない
> - 検索自体は完了しているように見えるが、Mery を操作できなくなる
再度確認したところ、現象が発生した場合は最終行のDocument.Activate()が動いていないようでしたので、FindInFilesから処理が戻ってきていないようです。ただ、検索結果自体は無事表示されています。
Mery自体はスクロールやタブの移動などは可能ですが、文字入力等は受け付けず、[ファイル] → [すべて閉じる] でもソフト自体は終了しないためタスクマネージャーで強制終了するしかない状態となります。> こちらでも引き続き検証しますので、使用されている設定や検索パス、検索対象に巨大なファイルが含まれているかどうかなど、お気づきの点がありましたら教えていただけると、問題解決の糸口になるかもしれません。
検証環境として【C:¥test】というフォルダを切って、中には200バイト程度のテキストファイルを2つ入れたのみ、という状況を準備し、そのうちの1つを対象にして確認しましたが、やはり発生します。
あと高確率で発生と書きましたが、1回目で即発生することはありますが、確率はそこまで高くない(体感6~8割程度)という印象です。2回3回と連続で実行……多くても5回目までには発生しています。| euclid | 返信 -
ご返信ありがとうございます。
> タブが有効の状態で、タブをウィンドウ外にドラッグすると新たにウィンドウが立ち上がると思いますが、それでできた新しいウィンドウを「サブのウィンドウ」と表現しています。
なるほど、そういうことでしたか。
マクロから、タブを分離して作成した別ウィンドウで GREP を実行するケースまでは、こちらでも十分に想定できていませんでした。
> 検証環境として【C:¥test】というフォルダを切って、中には200バイト程度のテキストファイルを2つ入れたのみ、という状況を準備し、そのうちの1つを対象にして確認しましたが、やはり発生します。
いただいた条件で試してみたところ、こちらの環境でも現象を確認できました。
ただ、最初の 3 回ほどは現象が発生したものの、その後は 100 回ほど繰り返しても再現せず…。
再現性にかなりばらつきがあるようです。何らかのマルチスレッド処理のタイミングによって、運悪くデッドロックのような状態が発生している可能性もあるかもしれません。
とはいえ、今回の操作には少し気になる点があります。
GREP 自体は別スレッドで検索を行うため、GREP 実行中でも別ウィンドウを操作できます。もちろん、GREP を実行しているウィンドウ自体は、基本的に操作できない状態になります。
一方、マクロから別ウィンドウで GREP を実行した場合、マクロを実行した元のウィンドウはマクロ実行中として基本的な操作が禁止され、GREP を実行しているウィンドウも検索中のため操作できません。
ただし、複数のウィンドウが開いている場合、それら以外のウィンドウでは通常どおり操作でき、マクロの実行も可能になります。
そのため、別のウィンドウから同じマクロを再度実行すると、すでに GREP を実行中の同じウィンドウに対して、さらに FindInFiles が呼び出される可能性があります。このあたりで検索処理の状態が競合し、問題が発生する可能性も考えられそうです。
ちょっと悩ましい状況なので、もう少し調べたうえで、対応方法を検討させてください。
| Kuro | 返信