线程同步Demo:SynchronizationContext和EventWaitHandle:异步和同步

涉及到两个类:FileUpload和调用方。
1、FileUpload上传是时使用异步方式,但需要向调用方(另一线程)发布状态信息(例子里只有上传完毕状态,实际可以包括进度等状态),
    调用方不想处理多线程问题,于是考虑SynchronizationContext
2、例子里调用方需要等待上传线程完成,于是用了EventWaitHandle,好像是找麻烦了,呵呵

ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Threading;
  6
  7namespace ConsoleApplication1
  8ExpandedBlockStart.gifContractedBlock.gif{
  9ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 10    /// 不同线程子键同步调用的辅助类
 11    /// </summary>

 12    internal sealed class OrderedSynchronizationContext : SynchronizationContext
 13ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 14ContractedSubBlock.gifExpandedSubBlockStart.gif        fields#region fields
 15        private Queue<KeyValuePair<SendOrPostCallback, object>> pendingCallbacks = new Queue<KeyValuePair<SendOrPostCallback, object>>();
 16        #endregion

 17
 18ContractedSubBlock.gifExpandedSubBlockStart.gif        functions#region functions
 19        public override void Post(SendOrPostCallback d, object state)
 20ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 21            lock (this.pendingCallbacks)
 22ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 23                this.pendingCallbacks.Enqueue(new KeyValuePair<SendOrPostCallback, object>(d, state));
 24                if (this.pendingCallbacks.Count == 1)
 25ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 26                    ThreadPool.QueueUserWorkItem(new WaitCallback(this.ProcessPendingCallbacks));
 27                }

 28            }

 29        }

 30
 31        private void ProcessPendingCallbacks(object state)
 32ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 33            KeyValuePair<SendOrPostCallback, object> pair = new KeyValuePair<SendOrPostCallback, object>();
 34            bool flag = false;
 35            do
 36ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 37                lock (this.pendingCallbacks)
 38ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 39                    if (this.pendingCallbacks.Count <= 0)
 40ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
 41                        break;
 42                    }

 43                    pair = this.pendingCallbacks.Dequeue();
 44                }

 45                pair.Key(pair.Value);
 46            }

 47            while (flag);
 48        }

 49        #endregion

 50    }

 51
 52    public delegate void UploadCompletedEventHandler();
 53
 54ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 55    /// 模拟异步文件上传
 56    /// </summary>

 57    class FileUpload
 58ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 59        public event UploadCompletedEventHandler Uploaded;
 60        private SynchronizationContext _syncContext;
 61        
 62        EventWaitHandle _waitHandle;
 63        
 64        public FileUpload(EventWaitHandle waitHandle)
 65ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 66            this._syncContext = SynchronizationContext.Current ?? new OrderedSynchronizationContext();
 67            this._waitHandle = waitHandle;
 68        }

 69
 70        public void Upload()
 71ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 72            Console.WriteLine("Upload.Begin");
 73            //模拟异步
 74            ThreadStart ts = new ThreadStart(DoUpload);            
 75            new Thread(ts).Start();            
 76        }

 77
 78        void DoUpload()
 79ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 80            //模拟上传
 81            for (int i = 0; i < 5; i++)
 82ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 83                Thread.Sleep(400);
 84                Console.WriteLine("uploading {0}", i);
 85            }

 86            Console.WriteLine("DoUpload.Completed");
 87            if (Uploaded != null)
 88ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 89                //调用外部事件
 90                if (SynchronizationContext.Current == this._syncContext)
 91ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 92                    Uploaded();
 93                }

 94                else
 95ExpandedSubBlockStart.gifContractedSubBlock.gif                {                 
 96                    _syncContext.Post(state =>
 97ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
 98                            Uploaded();
 99                            
100                            if (_waitHandle != null)
101ExpandedSubBlockStart.gifContractedSubBlock.gif                            {
102                                _waitHandle.Set();
103                            }

104                        }
null);
105                }

106            }

107        }

108    }

109
110    class Program
111ExpandedSubBlockStart.gifContractedSubBlock.gif    {
112        static void Main(string[] args)
113ExpandedSubBlockStart.gifContractedSubBlock.gif        {
114            ManualResetEvent asyncEvent = new ManualResetEvent(false);
115            FileUpload upload = new FileUpload(asyncEvent);
116            upload.Uploaded += () =>
117ExpandedSubBlockStart.gifContractedSubBlock.gif                {
118                    Console.WriteLine("上载事件触发!");
119                }
;
120            Console.WriteLine("开始调用上载");
121            upload.Upload();
122            Console.WriteLine("异步上载立即返回");
123            
124            asyncEvent.WaitOne();
125            Console.WriteLine("上载完毕!");
126        }
        
127    }

128}


结果:

开始调用上载
Upload.Begin...
异步上载立即返回
uploading 0...
uploading 1...
uploading 2...
uploading 3...
uploading 4...
DoUpload.Completed
上载事件触发!
上载完毕!

转载于:https://www.cnblogs.com/wangpy/archive/2009/09/21/1571251.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值