Silverlight中实现同步调用Service,核心是用到了MS的Interlocked.Increment.
Interlocked.Increment是做什么事情的?
如果有两个Thread ,分别记作threadA,threadB。
1:threadA将Value从存储空间取出,为0;
2:threadB将Value从存储空间取出,为0;
3:threadA将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
4:threadB将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
最后Value =1 ,而正确应该是2;这就是问题的所在,InterLockedIncrement 能够保证在一个线程访问变量时其它线程不能访问。
不废话了,直接上Demo了。
private BizModel bizModel = null;
|
int loadCompletedCount = 0;
|
RestService.Query<BizEntity>("/Biz1/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
RestService.Query<BizEntity>("/Biz2/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
RestService.Query<BizEntity>("/Biz3/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
private void UpdateUIAfterLoadData()
|
测试例子
public delegate void deleHeadler(object x, EventArgs e);
|
03 |
public class RestService
|
05 |
public static void Query<T>(string s, deleHeadler del)
|
08 |
for (int i = 0; i < 70000000; i++)
|
18 |
static void Main(string[] args)
|
20 |
int wellLoadedCount = 2;
|
21 |
int loadCompletedCount = 0;
|
23 |
RestService.Query<string>("1",
|
26 |
Interlocked.Increment(ref loadCompletedCount);
|
28 |
if (loadCompletedCount == wellLoadedCount)
|
30 |
UpdateUIAfterLoadData();
|
35 |
RestService.Query<string>("2",
|
38 |
Interlocked.Increment(ref loadCompletedCount);
|
40 |
if (loadCompletedCount == wellLoadedCount)
|
42 |
UpdateUIAfterLoadData();
|
48 |
private static void UpdateUIAfterLoadData()
|
50 |
Console.WriteLine("全部加载完毕");
|
Silverlight中实现同步调用Service,核心是用到了MS的Interlocked.Increment.
Interlocked.Increment是做什么事情的?
如果有两个Thread ,分别记作threadA,threadB。
1:threadA将Value从存储空间取出,为0;
2:threadB将Value从存储空间取出,为0;
3:threadA将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
4:threadB将取出来的值和1作加法,并且将和放回Value的空间覆盖掉原值。加法结束,Value=1。
最后Value =1 ,而正确应该是2;这就是问题的所在,InterLockedIncrement 能够保证在一个线程访问变量时其它线程不能访问。
不废话了,直接上Demo了。
private BizModel bizModel = null;
|
int loadCompletedCount = 0;
|
RestService.Query<BizEntity>("/Biz1/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
RestService.Query<BizEntity>("/Biz2/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
RestService.Query<BizEntity>("/Biz3/1000",(obj,args)=>
|
Interlocked.Increment(ref loadCompletedCount);
|
bizModel = args.Result.ToModel();
|
if (loadCompletedCount == wellLoadedCount)
|
private void UpdateUIAfterLoadData()
|