• SynchronizationContext


    SendOrPostCallback xxx = vg => { Text ="内部: "+vg.ToString(); };
    
                dynamic vx = new { a = SynchronizationContext.Current, b = xxx };
                Thread td = new Thread(x =>
                {
                    dynamic tmp = x;
                    
                    // SynchronizationContext ds = x as SynchronizationContext;
                    for (int i = 0; i < 500; i++)
                    {
                        System.Threading.Thread.Sleep(10);
                        //((SynchronizationContext)tmp.a).Post(v => { Text = v.ToString(); }, i + "   " + DateTime.Now);
                        ((SynchronizationContext)tmp.a).Post(tmp.b, i + "   " + DateTime.Now);
    
                    }
                  //  this.Invoke((MethodInvoker)delegate { MessageBox.Show("ok"); });
    
                });
                td.Start(vx);
    

      

      void uiexe(object cs)
            {
                Text = cs.ToString();
            }
    

      

    //ThreadPool.QueueUserWorkItem(x =>
                //{
                //    for (int i = 0; i < 100; i++)
                //    {
                //        System.Threading.Thread.Sleep(10);
                //        ((SynchronizationContext)x).Post(y => { Text = i + "   " + DateTime.Now; }, null);
                //    }
    
                //}, SynchronizationContext.Current);
    
                SynchronizationContext nb = SynchronizationContext.Current;
                ThreadPool.QueueUserWorkItem(x =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        System.Threading.Thread.Sleep(10);
                        nb.Post(y => { Text = i + "   " + DateTime.Now; }, null);
                    }
    
                }, null);
    

      

    [STAThread]
    
    static void Main()
    
    {
    
        Application.EnableVisualStyles();
    
        Application.SetCompatibleTextRenderingDefault(false);
    
    
    
        // let's check the context here
    
        var context = SynchronizationContext.Current;
    
        if (context == null)
    
            MessageBox.Show("No context for this thread");
    
        else
    
            MessageBox.Show("We got a context");
    
    
    
        // create a form
    
        Form1 form = new Form1();
    
    
    
        // let's check it again after creating a form
    
        context = SynchronizationContext.Current;
    
    
    
        if (context == null)
    
            MessageBox.Show("No context for this thread");
    
        else
    
            MessageBox.Show("We got a context");
    
    
    
        if (context == null)
    
            MessageBox.Show("No context for this thread");
    
    
    
        Application.Run(new Form1());
    
    }
    

      

    而且它使用非常方便,只需要关注下面两个方法即可:

    1.      Send:发送界面更新请求至主线程,阻塞当前线程直至返回。

    2.      Post:发送界面更新请求至主线程,不阻塞当前线程。

    实际上,他们都是同一个方法,只是 send 是同步,post 是异步

    这是一个很简单的例子,也许看过的人都会说:根本就没有摆脱Control  和 From 啊!

    诚然如此,为了摆脱Control,我们还需要封装一下,看下面的BackgroundWorker 类:

        class BackgroundWorker
        {
            public EventHandler<EventArgs> WorkerStarted;
            public EventHandler<ProgressEventArgs> ReportProgress;
            public EventHandler<EventArgs> WorkerCompleted;
    
            public SynchronizationContext Context { get; set; }
    
            public void Start()
            {
                Thread t = new Thread(() =>
                {
                    Context.Post(SetStartState, null);
    
                    for (int i = 0; i <= 10; i++)
                    {
                        Thread.Sleep(new TimeSpan(0, 0, 1));
                        Context.Post(UpdateProgress, i * 10);
                    }
    
                    Thread.Sleep(new TimeSpan(0, 0, 1));
                    Context.Post(SetCompletedState, null);
                }
                );
                t.Start();
            }
    
            private void SetStartState(object state)
            {
                if (WorkerStarted != null)
                {
                    WorkerStarted(this, new EventArgs());
                }
            }
    
            private void SetCompletedState(object state)
            {
                if (WorkerCompleted != null)
                {
                    WorkerCompleted(this, new EventArgs());
                }
            }
    
            private void UpdateProgress(object state)
            {
                if (ReportProgress != null)
                {
                    ReportProgress(this, new ProgressEventArgs {Progress = Convert.ToInt32(state)});
                }
            }
        }
    

      

    有两个特别的地方:

    1. 构造的时候,需要提供SynchronizationContext 实例

    2. 它的三个事件(WorkerStarted,ReportProgress, WorkerCompleted),都是在 post 方法里面触发的。这样做就可以确保事件的订阅方法脱离后台线程,进入主线程。

            protected override void OnLoad(EventArgs e)
            {
                _context = SynchronizationContext.Current;
            }
    
            private void btnWrapper_Click(object sender, EventArgs e)
            {
                btnWrapper.Enabled = false;
    
                BackgroundWorker worker = new BackgroundWorker {Context = SynchronizationContext.Current};
                worker.WorkerStarted += (o, args) => { txtWrapper.Text = "Running background thread..."; };
                worker.ReportProgress += (o, args) => { txtWrapper.Text = string.Format("Progress: {0}", args.Progress); };
                worker.WorkerCompleted += (o, args) =>
                {
                    txtWrapper.Text = "Background thread completed";
                    btnWrapper.Enabled = true;
                };
    
                worker.Start();
            }
    

      

        WebChannelFactory<JK.IXX> dd = new WebChannelFactory<JK.IXX>(new Uri("http://localhost/xxii"));
                //  ChannelFactory<JK.IXX> dd = new ChannelFactory<JK.IXX>(bd, "http://localhost/xxii");
                //   dd.Endpoint.Behaviors.Add(new WebHttpBehavior());
                //  WebOperationContext.Current.IncomingRequest.Headers.Add("dddd","ssss");
                dd.Endpoint.Behaviors.Add(new XEndpointBehavior());
    
                //SynchronizationContext.Current.Post(
                // SynchronizationContext
    
                JK.IXX service = dd.CreateChannel();
                IClientChannel clientchanel = service as IClientChannel;
    
                //IServiceChannel 
                using (OperationContextScope scope = new OperationContextScope(clientchanel))
                {
                    var xddd = WebOperationContext.Current;
    
    
                    xddd.OutgoingRequest.Headers.Add("ssss", "dddd" + DateTime.Now);
    
                    //加不了
                    //*****************************************************************************************
                    //using (OperationContextScope scope = new OperationContextScope(iContextChannel))
                    //{
                    //MessageHeader<string> mh = new MessageHeader<string>("abcde");
                    //MessageHeader header = mh.GetUntypedHeader("AuthKey", http://www.cjb.com/);
                    //OperationContext.Current.OutgoingMessageHeaders.Add(header);
    
                    //return func();
                    //}
    
                    //服务端: 
    
                    //string authKey = string.Empty;
                    //if (OperationContext.Current != null)
                    //{
                    //authKey = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("AuthKey", http://www.cjb.com);
                    //}
                    //*****************************************************************************************
    
    
                    //调用方法获取消息头  
                    string messHeader = service.getstr();
                    MessageBox.Show(messHeader);
                    Console.WriteLine(messHeader);
                    Console.WriteLine("服务方法已调用");
                }
    

      

  • 相关阅读:
    【CVPR2022】Lite Vision Transformer with Enhanced SelfAttention
    【CVPR2022 oral】MixFormer: Mixing Features across Windows and Dimensions
    【ARXIV2204】Vision Transformers for Single Image Dehazing
    【ARXIV2203】SepViT: Separable Vision Transformer
    【ARXIV2203】CMX: CrossModal Fusion for RGBX Semantic Segmentation with Transformers
    无法识别的GUID格式,程序以管理员权限启动
    linspace函数c++实现
    vs qt 提示框 中文乱码 洲际导弹
    VS编译Qt遇到无法运行rc.exe问题 洲际导弹
    vs QT 什么未声明标识符的问题 洲际导弹
  • 原文地址:https://www.cnblogs.com/xiangxiong/p/6802623.html
Copyright © 2020-2023  润新知