c# - 使用 BackgroundWorker 时 WPF UI 未更新
问题描述
我正在开发WPF
与服务器通信的客户端应用程序TCP/IP using sockets.
我有多个 WPF 表单,一旦加载应用程序,我就会连接到服务器
public partial class MainWindow : Window
{
public System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
clientSocket.Connect("127.0.0.1", 8888);
ShowMimic("CCRMain");
}
}
我过去常常BackgroundWorker
通过从服务器接收到的数据不断更新 UI。但不幸的是,UI 不会自动更新,但是当重新加载表单时,例如通过在表单之间来回切换,UI 会在以下加载事件的 b/c 下自行更新
private void Mimic_Loaded(object sender, RoutedEventArgs e)
{
MyWorker.RunWorkerAsync();
}
请让我知道,一旦应用程序通过套接字从服务器接收到数据,我的 UI 将如何自动更新。Data()
函数与服务器进行通信。
C# WPF 客户端应用程序
BackgroundWorker MyWorker = new BackgroundWorker();
int[] allRodPosition = new int[17];
public CCRMain()
{
InitializeComponent();
MyWorker.DoWork += MyWorker_DoWork;
MyWorker.RunWorkerCompleted += MyWorker_RunWorkerCompleted;
}
private delegate void UpdateMyDelegatedelegate(int i);
private void UpdateMyDelegateLabel(int i)
{
//label1.Content = "BckgroundWork:" + i.ToString();
}
private void MyWorker_DoWork(object Sender, System.ComponentModel.DoWorkEventArgs e)
{
UpdateMyDelegatedelegate UpdateMyDelegate = new UpdateMyDelegatedelegate(UpdateMyDelegateLabel);
DispatcherOperation op = Dispatcher.BeginInvoke((Action)(() =>
{
Data();
A1G1Text.Text = allRodPosition[0].ToString();
}));
}
private void MyWorker_RunWorkerCompleted(object Sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
}
void Data()
{
MainWindow mw = (MainWindow)Application.Current.MainWindow;
NetworkStream serverStream = mw.clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(A1G1.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)mw.clientSocket.ReceiveBufferSize);
System.IO.MemoryStream ms = new System.IO.MemoryStream(inStream);
System.IO.BinaryReader br = new System.IO.BinaryReader(ms);
int[] inComingData = new int[17];
for (int i = 0; i < 17; i++)
{
inComingData[i] = br.ReadInt32();
allRodPosition[i] = inComingData[i];
}
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
//MainWindow mw = new MainWindow();
MainWindow mw = (MainWindow)Application.Current.MainWindow;
mw.ShowMimic("DemandPosition");
}
private void Button2_MouseDown(object sender, MouseButtonEventArgs e)
{
//MainWindow mw = new MainWindow();
MainWindow mw = (MainWindow)Application.Current.MainWindow;
mw.ShowMimic("LiftCoil");
}
private void Mimic_Loaded(object sender, RoutedEventArgs e)
{
MyWorker.RunWorkerAsync();
}
}
解决方案
public partial class MainWindow : Window
{
private BackgroundWorker _backgroundWorker;
private Timer timer1;
public MainWindow()
{
InitializeComponent();
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += backgroundWorker_DoWork;
_backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
InitTimer();
}
public void InitTimer()
{
timer1 = new Timer();
timer1.Elapsed += Timer1OnElapsed;
timer1.Interval = 2000; // in miliseconds
timer1.Start();
}
private void Timer1OnElapsed(object sender, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
TxtToBeUpdated.Text = DateTime.Now.ToString(CultureInfo.InvariantCulture);
CallSocket();
});
}
private void CallSocket()
{
//do socket
}
}
尝试 Dispatcher.Invoke 在您的套接字调用后更新 UI 线程
推荐阅读
- sql - 如何重写oracle SQL语句以符合ansi-98并转换为DB2格式
- azure - 限制 Azure AD 用户访问 Web api 控制器
- rest - 表的不同字段上的多个 GET Rest API 或 DDD 中的一个 Rest API
- firebase - 可以使用 node-schedule 和 CloudFuntions Firebase 长时间安排任务
- wordpress - WooSquare 同步和重复 SKU
- c# - 如何以最有效的方式更改多个按钮上的文本,而无需在 C# 中重复代码?
- python - 如何使用 python 请求发送表单数据?
- r - 如何按项目计算分类变量的百分比?
- swift - 如何在不使用 Any 的情况下在 Swift 中存储具有关联类型的协议数组?
- c++ - 如何在不复制的情况下在结构中使用来自 stl 的容器