我試圖從另一個線程設置TextBox的Text屬性。我在下面得到了這個例外。如何修復我的後臺解決方案以進行線程安全調用?
"Cross-thread operation not valid: Control 'recTpcTxt' accessed from a thread other than the thread it was created on."
然後,我用BackgroundWorker來解決這個問題。但是,我面臨着同樣的異常信息。
編輯[1]: 其實我自己引導一下這個鏈接; https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx。我可以通過使用invokeproperty來解決我的問題。但是,我無法解決背景工作者的問題。
我的解決方案有什麼問題嗎?如何修復我的解決方案以設置UI變量的某些屬性?
編輯[2]:更多的代碼來澄清問題;
MqttManager.cs;
public partial class MqttManager : Form
{
MqttHandler mqttHandler = new MqttHandler();
public static MqttManager managerInst;
public MqttManager()
{
InitializeComponent();
managerInst = this;
...
}
...
private BackgroundWorker backgroundWorker;
public void NotifyUIForRecMsg(string topic, string message)
{
object[] objArr = { topic, message };
this.backgroundWorker.RunWorkerAsync(objArr);
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(5000);
e.Result = e.Argument;
}
private void backgroundWorker_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
object[] res = (object[])e.Result;
this.recTpcTxt.Text = (String)res[0];
}
}
MqttManager.Design.cs;
partial class MqttManager
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
...
this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork);
this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted);
}
#endregion
...
}
MqttHandler.cs;
class MqttHandler
{
MqttClient client;
...
/// <summary>
/// Publish received event handler.
/// </summary>
private void client_MqttMsgPublishReceived(Object sender, MqttMsgPublishEventArgs e)
{
MqttManager.managerInst.NotifyUIForRecMsg(e.Topic, Encoding.UTF8.GetString(e.Message));
}
}
閱讀你是濫用'BackgroundWorker'。它打算做後臺工作而不更新UI。爲什麼不從'NotifyUIForRecMsg'更新UI? –
@HamletHakobyan,我無法使用NotifyUIForRecMsg更新UI bu。我得到了上述的例外。 –
爲什麼'NotifyUIForRecMsg'在非UI線程中?您應該提供更多的代碼並澄清問題。 –