89

System.Timers.TimerAsp.Netアプリケーションでを使用していますが、をHttpServerUtility.MapPath介してのみ使用できるように見える方法を使用する必要がありますHttpContext.Current.Server.MapPath。問題はHttpContext.CurrentnullイベントTimer.Elapsedが発生したときです。

HttpServerUtilityオブジェクトへの参照を取得する別の方法はありますか?クラスのコンストラクターに注入できます。安全ですか?現在のリクエストの最後にガベージコレクションが行われないようにするにはどうすればよいですか?

ありがとう!

4

6 に答える 6

143

HostingEnvironment.MapPath()代わりに使用することが可能ですHttpContext.Current.Server.MapPath()

ただし、スレッドまたはタイマーイベントではまだ試していません。


私が検討したいくつかの(実行不可能な)ソリューション。

  • 私が気にする唯一の方法HttpServerUtilityはですMapPath。代わりに、これを使用AppDomain.CurrentDomain.BaseDirectoryしてパスを構築することもできます。ただし、アプリが仮想ディレクトリを使用している場合、これは失敗します(Mineは失敗します)。

  • 別のアプローチ:必要なすべてのパスをGlobalクラスに追加します。でこれらのパスを解決しますApplication_Start

于 2008-09-21T21:19:40.347 に答える
14

これで仮想ディレクトリの問題が解決するかどうかはわかりませんが、これを MapPath に使用します。

public static string MapPath(string path)
{
    if (HttpContext.Current != null)
        return HttpContext.Current.Server.MapPath(path);

    return HttpRuntime.AppDomainAppPath + path.Replace("~", string.Empty).Replace('/', '\\');
}
于 2009-01-27T23:31:21.050 に答える
13

HostingEnvironmentは、モックを作成するのが非常に難しいクラスであるため、完全なソリューションではありません(HostingEnvironment.MapPathを使用するテストコードを単体テストする方法を参照)。

テスト容易性が必要な場合は、 https://stackoverflow.com/a/1231962/85196で提案されているように、独自のパスマッパーインターフェイスを作成することをお勧めします。

public class ServerPathMapper : IPathMapper { 
 public string MapPath(string relativePath) { 
      return HostingEnvironment.MapPath(relativePath); 
 } 
} 

結果は簡単にモック可能であり、内部でHostingEnvironmentを使用し、同時にase69の懸念に対処する可能性さえあります。

于 2012-07-09T21:52:06.237 に答える
2

タイマーを開始する前に MapPath 関数を呼び出して、結果を単にキャッシュすることはできませんか? tickイベント内でMapPath呼び出しを行うことは絶対に必要ですか?

于 2008-09-21T20:23:50.247 に答える
2

タイマーが経過すると、現在の HTTP コンテキストはなくなります。これは、タイマー イベントが特定の HTTP 要求に関連していないためです。

あなたがすべきことは、HTTP コンテキストが利用可能な HttpServerUtility.MapPath を使用することです。これは、要求パイプライン イベント (Page_Load など) の 1 つ、または Application_Start などの Global.asax イベントで実行できます。

MapPath の結果を、Timer.Elapsed イベントからアクセスできる変数に割り当てます。ここで、必要な特定のファイルの場所を取得するために Path.Combine を使用できます。

于 2008-09-21T20:48:56.613 に答える
0

その時点で null である理由 (考えてみれば) は、タイマー経過イベントが HTTP 要求の一部として発生しない (したがって、コンテキストがない) ためだと思います。サーバー上の何かが原因です。

于 2008-09-21T20:23:41.167 に答える