【问题标题】:Setting a label text from data off a thread using .Net Compact/Windows CE使用 .Net Compact/Windows CE 从线程中的数据设置标签文本
【发布时间】:2018-06-12 19:43:56
【问题描述】:

我似乎无法找到有关如何执行此操作的可靠信息来源。我正在做的事情的细分。我有一个服务器/客户端正在运行,它在一个线程上运行。收到信息后,我需要将该信息放入标签中。

为了完全清楚,我想在标签中显示收到的消息。

我听课的代码:

        public void receiveMessage(IAsyncResult ar)
    {
        //read from client
        int bytesRead;
        try
        {
            lock (_client.GetStream())
            {
                bytesRead = _client.GetStream().EndRead(ar);
                //Console.WriteLine(ASCIIEncoding.ASCII.GetString(data, 0, bytesRead));
            }
            //if client has disconnected
            if (bytesRead < 1)
                return;
            else
            {
                //get the message sent
                string messageReceived =
                    ASCIIEncoding.ASCII.GetString(data, 0, bytesRead);   
                if (frmMain.InvokeRequired)
                {
                    frmMain.UpdateData(messageReceived);
                }
            }
            //continue reading from client
            lock (_client.GetStream())
            {
                _client.GetStream().BeginRead(
                    data, 0, _client.ReceiveBufferSize,
                    receiveMessage, null);

            }
        }
        catch (Exception ex)
        {

        }
    }

来自 frmMain.UpdateData 的代码:

        public void UpdateData(string text)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<string>(UpdateData), new object[] { text });
            return;
        }
        stat_bar.Text = text;
    }

这在普通桌面 win 表单应用程序上运行良好。但我需要在 WindowsCE/.NetCompact 框架内进行一些工作。

【问题讨论】:

  • 检查this answer
  • 那个答案让我在 else {} 中更新,当我这样做时它会跳过 else 语句。有什么提示吗?
  • 您是否尝试使用delegate 调用它? private delegate void UpdateDataDelegate(string text);this.Invoke(new UpdateDataDelegate(UpdateData), text);
  • 我还想知道new object[] { text } 是否是您方法的有效参数,因为Invoke 的第二个参数是params object[] args,这让我认为UpdateData 正在接收object[] { object[] { text } } .如果在stat_bar.Text = text; 行中设置断点,它会命中吗?

标签: c# .net compact-framework windows-ce


【解决方案1】:

要从另一个非 GUI 线程更新 GUI 元素,您需要使用委托和调用。我总是使用这种模式:

    delegate void SetTextCallback(string text);
    public void addLog(string text)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.txtLog.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(addLog);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            if (txtLog.Text.Length > 2000)
                txtLog.Text = "";
            txtLog.Text += text + "\r\n";
            txtLog.SelectionLength = 0;
            txtLog.SelectionStart = txtLog.Text.Length - 1;
            txtLog.ScrollToCaret();
        }
    }

您可以对所有类型的参数和元素执行此操作。

【讨论】:

  • 这与我尝试过的略有不同,但仍然不起作用。 .net compact 如此不同的某种原因,任何合理的想法似乎都行不通。
  • 上面的代码总是在我的表单(GUI线程)代码中使用。要从后台线程更新,您需要在 Thread 代码中添加委托,并在 Form 代码中添加事件处理程序,另请参阅 hjgode.de/wp/2010/06/01/…。顺便说一句:CF 在资源有限的设备上运行,因此减少了 API。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2012-03-29
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多