CSLAサービス側がマルチスレッドのソリューションをどのように使用するか
7488 ワード
前編では,非同期スレッドを用いてデータのプリロードを実現し,システム性能を向上させることについて述べた.このような操作は、一般に、ユーザの待ち時間を短縮するためにクライアントで実行される.クライアントは複数回の非同期要求を送信し、サービス側に到着した後、サービス側がマルチスレッド処理操作をサポートしない場合、各要求を線形に処理すると、必然的にクライアントの非同期要求が意味を持たなくなる.誰がサービス側を単一スレッドに設計するのか、明らかな間違いではないでしょうか.はい!しかし、私たちのシステムは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