2011年3月23日 星期三

Silverlight的RIA Services同步技術

 

image

需求:使用者可以選擇一般會員或創業會員,甚至同時選擇兩者,在按下確定,並處理完畢後,顯示訊息給使用者。

           預期的執行緒的執行順序是:一般會員=>創業會員=>提示訊息

架構
  1:         
  2: private MemberDomainContext dc = new MemberDomainContext();
  3: private Member member;
  4: //事件控制
  5: private static AutoResetEvent evt = new AutoResetEvent(false);

  1: //我們先用AutoResetEvent.WaitOne()來把還不需要執行的執行緒先擋住,先把資源留給要用的執行緒                
  2:                 if (GeneralCheckBox.IsChecked == true)
  3:                 {
  4:                     new Thread(new ThreadStart(() =>
  5:                     {
  6:                         LoadOperation<Role> loadOp = dc.Load(dc.GetRoleByRoleNameQuery("一般會員"), RoleLoadedCallback, null);
  7:                     })).Start();
  8:                 }
  9: 
 10:                 if (BusinessCheckBox.IsChecked == true)
 11:                 {
 12:                     new Thread(new ThreadStart(() =>
 13:                     {
 14:                         //等待一般會員的執行緒
 15:                         if ((options & RoleOptions.General) == RoleOptions.General)
 16:                             evt.WaitOne(); //擋住,不讓下面的敘述執行
 17: 
 18:                         LoadOperation<Role> loadOp = dc.Load(dc.GetRoleByRoleNameQuery("創業會員"), RoleLoadedCallback, null);
 19:                     })).Start();
 20:                 }
 21: 
 22:                 new Thread(new ThreadStart(() =>
 23:                 {
 24:                     //等待一般會員或創業會員的執行緒
 25:                     evt.WaitOne();
 26: 
 27:                     this.Dispatcher.BeginInvoke(() =>
 28:                     {
 29:                         MessageBox.Show("加入會員成功", "會員加入成功", MessageBoxButton.OK);
 30:                     });
 31: 
 32:                 })).Start();
  1: //對資料庫作變更的動作(非同步執行,這時候還沒有執行完成)   
  2:         private void RoleLoadedCallback(LoadOperation<Role> Op)
  3:         {
  4:             int roleId = Op.Entities.Select(r => r.RoleId).FirstOrDefault();
  5: 
  6:             UserRole ur = new UserRole();
  7: 
  8:             ur.RoleId = roleId;
  9:             ur.UserId = member.MemberId;
 10:             dc.UserRoles.Add(ur);
 11: //不使用AutoResetEvent的話,SubmitChanges會有衝突
 12:             dc.SubmitChanges(OnUserRoleSubmitCompleted, null);
 13:         }
  1: //變更資料庫完成,利用AutoResetEvent.Set()通知AutoResetEvent物件,可以把資源給別的執行緒使用了        
  2:         private void OnUserRoleSubmitCompleted(SubmitOperation so)
  3:         {
  4:             if (so.HasError)
  5:             {
  6:                 MessageBox.Show(string.Format("Submit Failed: {0}", so.Error.Message));                
  7:                 so.MarkErrorAsHandled();
  8:             }
  9:             evt.Set();
 10:             Thread.Sleep(1);
 11:         }

沒有留言:

張貼留言