CSLAサービス側がマルチスレッドのソリューションをどのように使用するか



前編では,非同期スレッドを用いてデータのプリロードを実現し,システム性能を向上させることについて述べた.このような操作は、一般に、ユーザの待ち時間を短縮するためにクライアントで実行される.クライアントは複数回の非同期要求を送信し、サービス側に到着した後、サービス側がマルチスレッド処理操作をサポートしない場合、各要求を線形に処理すると、必然的にクライアントの非同期要求が意味を持たなくなる.誰がサービス側を単一スレッドに設計するのか、明らかな間違いではないでしょうか.はい!しかし、私たちのシステムはCSLAを分散を実現するためのフレームワークとして使用していますが、そのサービス・エンド・プログラムは単一スレッドしかサポートできません......この問題はずっと解決したいと思っていましたが、CSLA公式フォーラムを調べたところ、著者はGlobalContextとClientContextのいくつかの理由で、マルチスレッドは一時的にサポートされていないと話しています.火が大きいのに,これはどうして使うのか.仕方なく現在システムはすでにこの枠組みに大きく依存しており、しばらくは新しいものを交換しようとするのも現実的ではない.だから自分でCSLAの中のコードを修正するしかありません:WCF通信クラスを修正してマルチスレッドのサービス端に修正して、まずサービス端の要求処理から着手しなければなりません.NET3.5のCSLAフレームワークはWCFを用いてデータ伝送を実現する.サーバ側でこのクラスを使用して受信します.1 namespace   Csla.Server.Hosts 2 { 3      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 4      [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 5      public   class   WcfPortal : IWcfPortal { } 6 }
このクラスには既にPerCallなので、このクラスは単一スレッド操作として設計されています.ここでは、装飾モードを使用して新しいクラスを構築します.
01

/// <summary>

02

///    ConcurrencyMode = ConcurrencyMode.Multiple

03

///         

04

/// </summary>

05

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,

06

    ConcurrencyMode = ConcurrencyMode.Multiple,

07

    UseSynchronizationContext = false)]

08

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

09

public class MultiThreadsWCFPortal : IWcfPortal

10

{

11

    private WcfPortal _innerPortal = new WcfPortal();

12

 

13

    #region IWcfPortal Members

14

 

15

    public WcfResponse Create(CreateRequest request)

16

    {

17

        return this._innerPortal.Create(request);

18

    }

19

 

20

    //...

21

 

22

    #endregion

23

}

  ,                      :

app.config:

1

<services>

1

<!--Csla.Server.Hosts.WcfPortal-->

1

    <service name="OpenExpressApp.Server.WPFHost.MultiThreadsWCFPortal" behaviorConfiguration="returnFaults">

2

        .....

3

    </service>

4

</services>

 

factory method:

1

private static Type GetServerHostType()

2

{

3

    return typeof(OpenExpressApp.Server.WPFHost.MultiThreadsWCFPortal);

4

    //return typeof(Csla.Server.Hosts.WcfPortal);

5

}

  ,          ,              。  ,                        。

 

  ApplicationContext._principal  

               ,   WCF         。            ,   NullRefrenceException  。       :

1

var currentIdentity = Csla.ApplicationContext.User.Identity as OEAIdentity;

2

currentIdentity.GetDataPermissionExpr(businessObjectId);

    ,Csla.ApplicationContext.User   UnauthenticatedIdentity   。         ,         “   ” ?     ,              ,CSLA                  。           CSLA     :

01

private static IPrincipal _principal;

02

public static IPrincipal User

03

{

04

    get

05

    {

06

        IPrincipal current;

07

        if (HttpContext.Current != null)

08

            current = HttpContext.Current.User;

09

        else if (System.Windows.Application.Current != null)

10

        {

11

            if (_principal == null)

12

            {

13

                if (ApplicationContext.AuthenticationType != "Windows")

14

                    _principal = new Csla.Security.UnauthenticatedPrincipal();

15

                else

16

                    _principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());

17

            }

18

            current = _principal;

19

        }

20

        else

21

            current = Thread.CurrentPrincipal;

22

        return current;

23

    }

24

    set

25

    {

26

        if (HttpContext.Current != null)

27

            HttpContext.Current.User = value;

28

        else if (System.Windows.Application.Current != null)

29

            _principal = value;

30

        Thread.CurrentPrincipal = value;

31

    }

32

}

     ,         WPF     ,                。                           ,             !  ,         BUG:     WPF          ,            。          WPF    ,                    。

                ,                。           ,          :

01

[ThreadStatic]

02

private static IPrincipal __principalThreadSafe;

03

private static IPrincipal __principal;

04

private static IPrincipal _principal

05

{

06

    get

07

    {

08

        return _executionLocation == ExecutionLocations.Client ? __principal : __principalThreadSafe;

09

    }

10

    set

11

    {

12

        if (_executionLocation == ExecutionLocations.Client)

13

        {

14

            __principal = value;

15

        }

16

        else

17

        {

18

            __principalThreadSafe = value;

19

        }

20

    }

21

}

               !    ,       ,             。        ,         [ThreadStatic]   ,     :                 。  ,               _principal   ,          ,         。

 

       

               :1、         ;2、     ApplicationContext.User    ,            。

             ?    !:)

           WCF          ,ApplicationContext.User        。               ,                   。     ApplicationContext.User      CSLA    ,         ,    NullRefrenceException……

                              ,             。        ,               ,           “   ”,      API,                ,               ,           (        Task   ……)。

1

public static void SafeInvoke(Action action)

2

{

3

    ThreadPool.QueueUserWorkItem(o => action());

4

}

             :

01

/// <summary>

02

///      wrapper   ,   action  ,               Principel。

03

///

04

///     :

05

///   ApplicationContext.User      ,

06

///            ,                    ,

07

///                    Principle       。

08

/// </summary>

09

/// <param name="action">

10

///      ApplicationContext.User,                 。

11

/// </param>

12

/// <returns></returns>

13

public static Action AsynPrincipleWrapper(this Action action)

14

{

15

    if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client)

16

    {

17

        return action;

18

    }

19

 

20

    var principelNeed = ApplicationContext.User;

21

 

22

    return () =>

23

    {

24

        var oldPrincipel = ApplicationContext.User;

25

        if (oldPrincipel != principelNeed)

26

        {

27

            ApplicationContext.User = principelNeed;

28

        }

29

 

30

        try

31

        {

32

            action();

33

        }

34

        finally

35

        {

36

            if (oldPrincipel != principelNeed)

37

            {

38

                ApplicationContext.User = oldPrincipel;

39

            }

40

        }

41

    };

42

}

   API  :

1

public static void SafeInvoke(Action action)

2

{

3

    action = action.AsynPrincipleWrapper();

4

 

5

    ThreadPool.QueueUserWorkItem(o => action());

6

}

1

      :       ,             ApplicationContext.User。

1

  

1

<strong>  </strong>

1

          CSLA              。      CSLA          。

view sourceprint?

1

        GIX4      ,                         。



http://www.cnblogs.com/zgynhqf/archive/2010/07/01/1769228.html