6

静的コード分析からのいくつかの警告を取り除くことに取り組んでいます。ある特定のケースでは、 で破棄が行われませんでしたManualResetEvent

問題のコードはFunc、メイン スレッドで a を実行し、呼び出し元のスレッドを一定のミリ秒ブロックします。これは奇妙なことのように聞こえますが、この質問の範囲外ですので、ご容赦ください。

using次のようなステートメントを追加するとします。

object result = null;
using (var completedEvent = new ManualResetEvent(false))
{
    _dispatcher.BeginInvoke((Action)(() =>
        {
            result = someFunc;
            completedEvent.Set();  // Here be dragons!
        }));

    completedEvent.WaitOne(timeoutMilliseconds);
    return result;
}

今、これが問題を引き起こす可能性が高いことに気づきました。私もたまたまResharperを使用しており、「破棄されたクロージャへのアクセス」というメッセージが表示されます。

Resharper は、問題のある行を次のように変更することで、これを修正することを提案しています。

if (completedEvent != null)
{ 
    completedEvent.Set();
}

さて、提案された解決策は私を困惑させます。通常の状況では、ステートメントnullによって変数が設定される理由はありません。クローズされた変数が破棄された後に変数が存在することを保証する、.NET のクロージャーの実装の詳細はありますか?usingnull

おまけの質問として、廃棄の問題に対する適切な解決策は何でしょうManualResetEventか?

4

3 に答える 3

6

ReSharper の「クイック フィックス」と「コンテキスト アクション」を混同しています。ReSharper が何かを修正することを提案するとき、ほとんどの場合、そこに電球が表示されます。この警告に対する簡単な修正がないため、ここに電球は表示されません。

しかし、迅速な修正とは別に、ReSharper には「コンテキスト アクション」もあり、いくつかの日常的なタスクを実行できます (小さなリファクタリングのようなものと考えてください)。ReSharper にカーソル下のコードのコンテキスト アクションがある場合、選択が表示されます。ここには、"Check if something is not null" というコンテキスト アクションがあります。警告とは関係がなく、変数を破棄した後に null に設定するという規則はありません。

また、Alt-Enter を押すと、ReSharper がこの警告に対する迅速な修正を提案しないという印象を与えるため、取り消し線が引かれた電球が表示されますが、コメントで無効にすることができます。実際、これがこの警告を簡単に消す唯一の方法です。しかし、代わりにこのコードを書き直します。

于 2013-01-09T06:29:37.510 に答える
2

私はほんの数時間前にまさにこれに遭遇しました。

誤警報です。R# は、イベントが設定されるまで実行がブロックされることを理解していません。

IMOそれは良い解決策です。R# は無視してください。

タイムアウトの期限が切れてイベントが破棄された場合に備えて、ObjectDisposedException呼び出し時に をキャッチすることをお勧めします。completedEvent.Set()これで R# の警告が回避されるとは思いませんが、安全です。

于 2013-01-08T15:55:23.247 に答える
1

nullをチェックする必要があり、さらにこの例外をキャッチする必要があると思います。someFuncを超えるとどうなるか想像してみてくださいtimeoutMilliseconds

于 2013-01-08T16:06:55.523 に答える