none
为什么WCF异步效果不明显? RRS feed

  • 问题

  • 我在主窗口上,做了一个ToolStrip,上面添加了许多ToolStripButton,用来打开相应Form,每个Form上操作相应数据表。为了让所有用户能够及时得知他人对数据所作的更改,我在主窗口启动时,做了个查询,检测是否有最新数据,若有,ToolStripButton红色醒目显示。
    因为耗时较长,同步查询时界面无法响应用户操作,便改为异步,但在异步执行完毕前,仍然无法点击ToolStripButton,也就是说,仍然无法响应用户操作。该怎么办呢?


    相关代码类似如下:


     Private Sub NewUpdated()
            '查询各模块最近是否有更新
            Dim q = From button In Me.ToolStrip.Items.Cast(Of ToolStripItem) Where TypeOf item Is ToolStripButton
            For Each button In q
               Try
                    Me.Service.GetTzAsync(button)
                Catch ex As ServiceModel.CommunicationException
     '显示错误信息
                End Try
            Next
      End Sub
     
        '若有新的更新,按钮背景显示为红色
        Private Sub GetTzCompleted(sender As Object, e As Service.GetTzCompletedEventArgs) Handles Service.GetTzCompleted
            If e.Error IsNot Nothing Then
               '显示错误信息
            Else
                CType(e.UserState, ToolStripButton).BackColor = Color.Red
            End If
        End Sub
     



    韩立学





    2019年3月20日 8:39

答案

全部回复

  • Hi,
    调用异步方法需要等待,把你的事件或者方法改为异步. 下面的示例展示了这一点。

    private async void button1_ClickAsync(object sender, EventArgs e)
            {
                ServiceReference1.CalculatorClient client = new ServiceReference1.CalculatorClient();
                var result = await client.AddAsync(3.56, 3.73);
                this.label1.Text = $"the Result is {result}";
            }
    
            Thread backthread = null;
            private void button2_Click(object sender, EventArgs e)
            {
                CheckForIllegalCrossThreadCalls = false;
                backthread = new Thread(new ThreadStart(RegService));
                backthread.Start();
            }
    
            private void RegService()
            {
                ServiceReference1.CalculatorClient client = new ServiceReference1.CalculatorClient();
                var result = client.Add(3.56, 3.73);
                this.label1.Text = $"the Result is {result}";
            }
    
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                    backthread.Abort();
                    Application.Exit();
            }


    WCF方法.

        public class Calculator : ICalculator
        {
            public double Add(double a, double b)
            {
                Thread.Sleep(5000);
                return a + b;
            }
        }

    使用同步方法,需要注意,在Vista以上操作系统不允许后台线程更改前端UI(Session隔离),需要显式地设置 CheckForIllegalCrossThreadCalls = false
    https://msdn.microsoft.com/zh-cn/ee791007.aspx
    Abraham


    2019年3月21日 3:26
  • 非常感谢您的回复!

    我的服务引用,是由系统自动生成的异步操作,GetTzAsync并无返回值(同步方法GetTz有返回值),无法使用Async和Await,怎么处理?

    刚接触异步,如果您能结合我的例子说明,会更有助于我理解。

    谢谢!


    韩立学


    2019年3月21日 5:51
    • 已标记为答案 大海怪 2019年3月22日 11:04
    2019年3月22日 1:59
  • 我用的是.NET 4, 所以有些功能不支持

    韩立学

    • 已标记为答案 大海怪 2019年3月22日 11:05
    2019年3月22日 11:05