• 使用Task简化Silverlight调用Wcf(续)


    上一篇使用Task简化Silverlight调用Wcf介绍了Silverlight下使用Task的一些方法,这篇继续改进一下。

    改进生成工具的生成的方法

    上次生成的代码如下,这些TaskAsync只是简单的包装一下Wcf的begin和end方法:

    public Task DoWorkTaskAsync()
    {
        return Task.Factory.FromAsync(this.Channel.BeginDoWork, this.Channel.EndDoWork, null);
    }
    public Task<DateTime> GetSerivceTimeTaskAsync()
    {
        return Task<DateTime>.Factory.FromAsync(this.Channel.BeginGetSerivceTime, this.Channel.EndGetSerivceTime, null);
    }

    调用时需要手动去Wait():

    private void OnGetTimeClick(object sender, RoutedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem(s =>
        {
            var task = _systemServiceClient.GetSerivceTimeTaskAsync();
            task.Wait();
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(task.Result.ToString());
            });
        });
    }

    这次生成的方法连task1.Wait(); 也包含了,多生成一个方法来Wait:

    public Task DoWorkTaskAsync()
    {
        return Task.Factory.FromAsync(this.Channel.BeginDoWork, this.Channel.EndDoWork, null);
    }
    public void DoWork()
    {
        var task = DoWorkTaskAsync();
        task.Wait();
    }
    
    public Task<DateTime> GetSerivceTimeTaskAsync()
    {
        return Task<DateTime>.Factory.FromAsync(this.Channel.BeginGetSerivceTime, this.Channel.EndGetSerivceTime, null);
    }
    public DateTime GetSerivceTime()
    {
        var task = GetSerivceTimeTaskAsync();
        task.Wait();
        return task.Result;
    }

    这样调用包含Wait的方法就直接返回结果了,而不是返回Task,再去Wait():

    private void OnGetTimeClick(object sender, RoutedEventArgs e)
    {
        ThreadPool.QueueUserWorkItem(s =>
        {
            var time = _systemServiceClient.GetSerivceTime();
            Dispatcher.BeginInvoke(() => MessageBox.Show(time.ToString()));
        });
    }

    UI同步技巧

    调用Wcf和UI交互需要顺序进行是最平常的需求,这时需要与UI交互也有“同步”的能力。例如:

    ThreadPool.QueueUserWorkItem(s =&gt;
    {
        //调用Wcf
        var num = _systemServiceClient.GetNum(5);
        //UI对话框询问是否继续
        var result = childWin.ShowSync();
        if(result == false)
            return;
    
        var time = _systemServiceClient.GetSerivceTime();
        .......
    });

    如果是UI线程的话是不可以这样阻塞的,然而这里是后台线程,阻塞也是没所谓的,所以可以使用下面的方法来阻塞线程,来模拟同步:

    public partial class TestChildWindow : ChildWindow
    {
        private readonly ManualResetEvent _manualResetEvent;
    
        public TestChildWindow()
        {
            InitializeComponent();
            _manualResetEvent = new ManualResetEvent(false);
            Closed += (_, __) => _manualResetEvent.Set();
        }
    
        public bool? ShowSync()
        {
            if (Dispatcher.CheckAccess())
                throw new InvalidOperationException("ShowSync只能使用后台线程调用!");
    
            Dispatcher.BeginInvoke(Show);
            _manualResetEvent.Reset();
            _manualResetEvent.WaitOne();
            return DialogResult;
        }
        .........
    }

    这里使用ManualResetEvent类来等待,打开窗体后马上阻塞,直到子窗体Closed时通知结束,实现”同步“。

    这里注意ShowSync的Dispatcher.CheckAccess()判断,明确只能再后台线程里调用。

    示例:

    private void OnMultiTaskClick(object sender, RoutedEventArgs e)
    {
        var childWin = new TestChildWindow();
        ThreadPool.QueueUserWorkItem(s =>
        {
            const string format = "Num:{1},{0}{2},{0}Time:{3},{0}UserCount:{4},{0}ChildWinResult:{5}";
            var num = _systemServiceClient.GetNum(5);
            var str = _systemServiceClient.SayHiTo(num.ToString());
    	//这里是“同步”的
            var result = childWin.ShowSync();
    
            var time = _systemServiceClient.GetSerivceTime();
            var all = _userServiceClient.GetAll();
            var msg = string.Format(format, Environment.NewLine, num, str, time, all.Count, result);
            Dispatcher.BeginInvoke(() => MessageBox.Show(msg));
        });
    }
    image

    工具和测试源码

  • 相关阅读:
    5 Things Every Manager Should Know about Microsoft SharePoint 关于微软SharePoint每个经理应该知道的五件事
    Microsoft SharePoint 2010, is it a true Document Management System? 微软SharePoint 2010,它是真正的文档管理系统吗?
    You think you use SharePoint but you really don't 你认为你使用了SharePoint,但是实际上不是
    Introducing Document Management in SharePoint 2010 介绍SharePoint 2010中的文档管理
    Creating Your Own Document Management System With SharePoint 使用SharePoint创建你自己的文档管理系统
    MVP模式介绍
    权重初始化的选择
    机器学习中线性模型和非线性的区别
    神经网络激励函数的作用是什么
    深度学习中,交叉熵损失函数为什么优于均方差损失函数
  • 原文地址:https://www.cnblogs.com/lemontea/p/2890586.html
Copyright © 2020-2023  润新知