2016-03-22 21 views
1

ASP.Netプロジェクトで、私は最近いくつかの長い関数を非同期に変更しました。これは明らかにされていない問題を引き起こすことが判明しました。ASP.Netから非同期関数を呼び出す

基本的には、関数はawaitを使用しているときに機能していますが、別の非同期関数から呼び出すと、フォームの問題となります。 これまで、Asyncをページ指示にtrueを設定し、RegisterAsyncTaskを使用して非同期関数の呼び出しを開始しました。コールは機能します。しかし、非同期ページディレクティブを有効にすると、ユーザーコンテキストが変更されることがあります。

特定のページのすべてのコードに対して呼び出し元ユーザーを指定するために、System.Web.UI.PageクラスをImpersonatedPageに継承しました。私のクラスでは、OnLoadを使用して呼び出し元のユーザーをimporsonateします。このようにして、私はユーザーがもう見ることができない、またはそれ以上のことをすることができないと確信しています。また、監査ログには正しいユーザーが表示されます。

非同期ページディレクティブを有効にすると、ユーザーを偽装します。しかし、例えば、ボタンクリックのコードでは、ユーザーコンテキストはアプリケーションプールのコンテキストに戻っています。 Page_Loadでは、ユーザーコンテキストが期待通りに呼び出し側のユーザーになります。 これが原因で、アプリケーションプールユーザーに切り替わることを回避できますか?

また、非同期ページディレクティブを削除し、Task.Runを使用して非同期関数を呼び出してみました。その後、ユーザーコンテキストは元に戻りませんが、代わりにHttpContext.Currentがnullで、async関数がその作業を行うことができません。

Asyncページディレクティブを有効にせずにASP.Netからasync関数を呼び出す他の方法はありますか?

ターゲットフレームワーク:

public class ImpersonatedPage : System.Web.UI.Page 
{ 
    WindowsImpersonationContext m_wic = null; 

    protected override void OnLoad(EventArgs e) 
    { 
     WindowsIdentity wi = (WindowsIdentity)System.Web.HttpContext.Current.User.Identity; 
     m_wic = wi.Impersonate(); 
     HttpContext.Current.Response.Write("Impersonate<br />"); 
     base.OnLoad(e); 
    } 

    protected override void OnUnload(EventArgs e) 
    { 
     base.OnUnload(e); 
     _ImpersonationUndo(); 
    } 

    protected void _ImpersonationUndo() 
    { 
     if (m_wic != null) 
     { 
      m_wic.Undo(); 
      HttpContext.Current.Response.Write("Impersonate undo<br />"); 
     } 
     m_wic = null; 
    } 
} 

フォームpageディレクティブ:

<%@ Page Async="true" Language="C#" AutoEventWireup="true" Inherits="ProxyAddresses" Codebehind="ProxyAddresses.aspx.cs" %> 

クラスの宣言:

public partial class ProxyAddresses : ImpersonatedPage 
.6.1 私の知る限り何も癖が

ImpersonatedPageクラスを有効にしません210

をPage_Load:

protected void Page_Load(object sender, EventArgs e) 
{ 
    Response.Write("Page_Load: " + WindowsIdentity.GetCurrent().Name + "<br />"); 

    if (!IsPostBack) 
    { 
     RegisterAsyncTask(new PageAsyncTask(InitialPageLoadAsync)); 
    } 
    ... 

非同期FUNC:

private async Task InitialPageLoadAsync() 
{ 
    Response.Write("InitialPageLoadAsync: " + WindowsIdentity.GetCurrent().Name + "<br />"); 

    await fnDoSomeAsyncWork(); 
    ... 

ボタンのクリック:

protected void idBtnSaveSrv_Click(object sender, EventArgs e) 
{ 
    Response.Write("idBtnSaveSrv_Click: " + WindowsIdentity.GetCurrent().Name + "<br />"); 
    ... 

デバッグ出力 - 初期要求:

  • 偽装
  • Page_Load:DOMAIN \ myuser
  • InitialPageLoadAsync:IIS APPPOOL \ appuser(なぜですか?

    • 偽装
    • をPage_Load:ドメイン\ myuserの
    • idBtnSaveSrv_Click:IIS APPPOOLの\ APPUSER(ボタンクリック - )
    • [ページ内容]
    • 偽装は

    デバッグ出力を元に戻しますなぜ?)

  • [ページのコンテンツ]
  • 偽装は、詳細なhere、フォームのpageディレクティブのAsync="true"が欠落しているかのようにそれが表示されます
+2

いくつかのコードを投稿してください。 –

+1

Page_Loadで非同期呼び出しを作成する場合は、非同期無効を宣言する必要があります。**ではなく、RegisterAsyncTaskを使用します。 RegisterAsyncTaskが現在のリクエストが –

+0

ほとんどあまりにも簡単かつ明白な終了時に中止されるべきではない実行中のタスクについてのIISに通知するためのものです...ここに例を踏襲し、その後、私はしかし、私はそれを試してみました、それが動作しませんでした:[リンク](http://www.asp.net/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45)とにかく、Page_Load asyncを完璧に動作させるように見える。 – Jan

答えて

1

を元に戻します。代わりにこれを試してみてください:

<%@ Page Async="true" Language="C#" Async="true" 
    AutoEventWireup="true" Inherits="ProxyAddresses" 
    Codebehind="ProxyAddresses.aspx.cs" %> 
関連する問題