0

次のコードは、対応する URL にアクセスするときに例外をスローします。のオブジェクトは のオブジェクトと同じstateではありません。なぜこうなった?の側で有効なオブジェクトを取得するにはどうすればよいですか?StartNew()ctxProcessRequestHttpContextBaseStartNew()

using System.Web;
using System.Web.Routing;

namespace AsyncUseHttpContextBaseWillFail
{
    public class FooHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            var ctx = new HttpContextWrapper(context);
            System.Threading.Tasks.Task.Factory.StartNew(state =>
            {
                //ArgumentException: Value does not fall within the expected range.
                var ip = ((HttpContextBase)state).Request.UserHostAddress;
            }, ctx);
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.Add(new Route(string.Empty, new FooRoute()));
        }
    }

    public class FooRoute : IRouteHandler
    {
        public virtual IHttpHandler GetHttpHandler(RequestContext context)
        {
            return new FooHandler();
        }
    }
}
4

2 に答える 2

1

上記のスティーブのコメントは、これを正しく機能させるための最善の策です。IHttpAsyncHandler または HttpTaskAsyncHandler を使用します。有効な HttpContext[Base] をコールバックに渡すことができたとしても、ProcessRequest が既に返されている場合は、ASP.NET ランタイムが HttpContext インスタンスをクリーンアップしている可能性があり、破棄されたオブジェクトを操作しようとすることになります。この問題を回避するために、非同期作業は常に非同期ハンドラーによって実行する必要があります。

于 2013-01-20T19:43:41.877 に答える
0

必要なデータを からローカル変数にコピーし、HttpContextこれらの変数をラムダで使用します。HttpContext2 番目のスレッドから にアクセスするのは安全ではありません。

于 2013-01-20T20:25:13.230 に答える