从不同的线程更新UI中的控件

时间:2016-11-07 20:44:43

标签: c# .net winforms

我有一个M2MQTT客户端订阅了DashboardViewModel类中的主题。在消息接收时,通过调用Writelog来更新UI。

public class DashboardViewModel : Object, IDashboardViewModel
{
    private IDashboardView View { get; }

    public DashboardViewModel(IDashboardView view)
    {
        View = view;

        mqttClient = new MqttClient("localhost");
        mqttClientId = Guid.NewGuid().ToString();
        mqttClient.MqttMsgPublishReceived += mqttClient_MsgPublishReceived;
        mqttClient.Subscribe(new string[] { "Home/Temperature" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
        mqttClient.Connect(mqttClientId);
        //...
    }

    private void mqttClient_MsgPublishReceived(object sender, MqttMsgPublishEventArgs eventArgs)
    {
        string message = Encoding.UTF8.GetString(eventArgs.Message);
        View.Writelog(message);
    }
}

FrmMain上的文本框没有更新; tbxLogs.InvokeRequired总是返回false,即tbxLogs.AppendText总是执行。有什么建议吗?

public partial class FrmMain : Form, IDashboardView
{
    private IDashboardViewModel dashboardViewModel = null;
    private delegate void WriteLogCallback(string text);

    public FrmMain()
    {
        InitializeComponent();
    }

    public void Writelog(string text)
    {
        if (tbxLogs.InvokeRequired)
        {
            WriteLogCallback callback = new WriteLogCallback(Writelog);
            tbxLogs.Invoke(callback, new object[] { text });
        }
        else
        {
            tbxLogs.AppendText(text + "\n");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为您需要使用调度程序:)

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action<String>(Writelog), message);

此方法内部

 private void mqttClient_MsgPublishReceived(object sender, MqttMsgPublishEventArgs eventArgs)
{
    string message = Encoding.UTF8.GetString(eventArgs.Message);
    //here instead of View.Writelog(message);
}