2016-11-07 150 views
-1

我有一个M2MQTT客户端订阅了DashboardViewModel类中的主题。在消息接收时,通过调用Writelog来更新UI。从不同线程更新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"); 
     } 
    } 
} 
+0

要开始,我会尝试把一个断点'View.WriteLog(消息)'看看'message'的内容是什么 –

+0

你确定它总是假?在需要时您正在调用相同的方法。是否有可能第一次围绕它是假的,它确实会调用该方法,所以第二次是假的?您是否尝试在tbxLogs.Invoke(...)行中放置断点?您是否收到错误,说需要调用? – JuanR

+0

谢谢各位反馈!信息的内容是我所期望的;如果(tbxLogs.InvokeRequired)设置了断点,并且在我逐步执行代码时,我可以看到它总是进入else部分。我没有得到一个错误;内容只是永远不会显示在控件中。 – Pieter

回答

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); 
} 
+0

谢谢......我会尝试调度员。 – Pieter

+0

当然...试一试并共享结果:)\ –

+0

看起来好像在WPF环境中使用Dispatcher,而在Win Forms中使用Invoke,BeginInvoke和InvokeRequired,我在原始文章中忘记提及的是我有一个Win Forms应用程序:(... – Pieter