1

私は AsyncController を OrchardProject で動作させることに取り組んでいます。私が使用している現在のバージョンは 2.2.4.9.0 です。

通常の MVC3 バニラ アプリケーションで正常に動作するhttp://www.pastie.org/2117952 (AsyncController) という コードを 2 人に 注目してもらいました。

基本的に、IndexCompleted にはルーティングできますが、Index にはルーティングできません。プロジェクト全体の Autofac 構成に何かが欠けていると思います。

構成は global.asax にあると思います: http://pastie.org/2118008

私が探しているのは、これが AsyncController に autofac を実装する正しい方法であるかどうか、または実装/初期化/などする必要がある何か/場所があるかどうかについてのガイダンスです。

〜ダン

4

4 に答える 4

2

IActionInvokerオーチャードは、と呼ばれる独自のを登録しているように見えますOrchard.Mvc.Filters.FilterResolvingActionInvoker

このクラスは。から派生しControllerActionInvokerます。推測では、非同期アクションをサポートするには、代わりにから派生する必要がありますAsyncControllerActionInvoker

お役に立てれば!

ニック

于 2011-07-05T21:40:21.753 に答える
0

Autofacの設定は問題ないように見えます。何かに移動できる限り、あなたの仮定が理にかなっているとは言えません。また、global.asaxの初期化に使用しているパターンは、のユーザーにも使用されています。

AsyncController場合、非同期メソッドはペアで提供される必要がありIndexAsyncますIndexCompleted。これらは一緒にIndexアクションを表します。IndexCompletedに移動できると言うとき、それはURL ".... / IndexCompleted"を開くことを意味しますか?

また、これはどのドキュメントからも確認できませんAsyncControllerが、すべてのアクションが非同期である必要があると思います。したがって、あなたのNewMessage行動は問題を引き起こし、非同期NewMessageAsyncNewMessageCompletedペアに変換する必要があります。

于 2011-06-29T12:48:17.510 に答える
0

の代わりに基づいてAsyncController簡単に変更できるものが必要でした。FilterResolvingActionInvokerAsyncControllerActionInvokerControllerActionInvoker

しかし、リクエストの完了後に自動的にトランザクションが破棄されるため、別の問題がありました。AsyncController開始スレッドとリクエストを完了するスレッドは異なる場合があり、クラスの Dispose メソッドで次の例外をスローしますTransactionManager

ATransactionScopeは、それが作成されたのと同じスレッドで破棄する必要があります。

この例外はログなしで抑制されており、実際に見つけるのは困難でした。この場合、セッションは破棄されないままになり、後続のセッションはタイムアウトになります。
だから私は、データベースへのクエリが必要なときはいつでもITransactionManager、私AsyncControllerはそれをラップします:

using (_services.TransactionManager) {
    .....
}

新しい TransactionManager :

public interface ITransactionManager : IDependency, IDisposable {
    void Demand();
    void Cancel();
}

public class TransactionManager : ITransactionManager {
    private TransactionScope _scope;
    private bool _cancelled;

    public TransactionManager() {
        Logger = NullLogger.Instance;
    }

    public ILogger Logger { get; set; }

    public void Demand() {
        if (_scope == null) {
            Logger.Debug("Creating transaction on Demand");
            _scope = new TransactionScope(
                TransactionScopeOption.Required, 
                new TransactionOptions { 
                    IsolationLevel = IsolationLevel.ReadCommitted 
                });
            _cancelled = false;
        }
    }

    void ITransactionManager.Cancel() {
        Logger.Debug("Transaction cancelled flag set");
        _cancelled = true;
    }

    void IDisposable.Dispose() {
        if (_scope != null) {
            if (!_cancelled) {
                Logger.Debug("Marking transaction as complete");
                _scope.Complete();
            }

            Logger.Debug("Final work for transaction being performed");
            try {
                _scope.Dispose();
            }
            catch {
                // swallowing the exception
            }
            Logger.Debug("Transaction disposed");
        }
        _scope = null;
    }
}

に他の小さな変更を加えたことに注意してくださいTransactionManager

于 2012-05-15T10:30:25.717 に答える
0

AsyncControllerActionInvoker ルートも試してみましたが、役に立ちませんでした。Orchard 自体から断続的なエラーが発生し、次のエラーが表示されます。

Orchard.Exceptions.DefaultExceptionPolicy - An unexpected exception was caught
System.TimeoutException: The operation has timed out.
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.ReflectedAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3f.<BeginInvokeAsynchronousActionMethod>b__3e(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
NHibernate.Util.ADOExceptionReporter - While preparing SELECT this_.Id as Id236_2_, this_.Number as Number236_2_,...<blah blah blah>
NHibernate.Util.ADOExceptionReporter - The connection object can not be enlisted in transaction scope.

したがって、独自のデータベース呼び出しをトランザクション オブジェクトでラップするだけでは効果がないと思います。オーチャードの内部も変更する必要があります。

Orchard でサポートされている AsyncControllers が必要な場合は、この問題に投票してください。

https://orchard.codeplex.com/workitem/18012

于 2013-06-01T04:13:47.043 に答える