C#使用异步或者多线程更新WPF中DataGrid的值

wpf使用异步更新界面值

1.要更新的DataGrid的值,如下面的FilePaths
private string filePaths;
/// <summary>
 /// 文件类型
 /// </summary>
 public string FilePaths
 {
     get { return filePaths; }
     set
     {
         //filePaths = value;
         //RaisePropertyChanged(FilePaths);
         Set(ref filePaths, value);//这里是比对当前值后以前值有无变化,有变化则跟新
     }
 }
 
2.c# 数组中的空值,使用C#删除数组中的空白值
string[] test={"1","","2","","3"};
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();
3.异步更新
System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
    {
           Definitions.SetPaths[Convert.ToInt32(setPaths.FileNumbers) - 1].FilePaths = fd.FileName;
   }));
   
4.async 和 await
async
public void Send()
{
 Task.Run(async () =>
   {
       return await sport.SendFile(FilePaths, FileTransmitType.XModem_1K, 5);
     }).GetAwaiter().OnCompleted(() => { });
 }

await

//串口通信部分发送文件的代码
/// <summary>
/// 发送文件
/// </summary>
/// <param name="fileName">文件路径</param>
/// <param name="type">传输协议类型</param>
/// <param name="retryCount">重试次数</param>
/// <param name="sendProgress">发送进度,int1为发送数据包长度,send2为当前发送包的编号</param>
/// <param name="token">取消令牌,超时等待时可以在外部取消等待。在调用异步方法时,上次的任务可能还没结束,再次调用会导致当前任务读取不到数据。这种场景建议调用前先取消之前的任务。</param>
/// <returns></returns>
public async Task<bool> SendFile(string fileName, FileTransmitType type, int retryCount, Action<int, int> sendProgress = null, CancellationToken token = default)
{
     if (fileName != null)
     {
         var result = false;
         if (type == FileTransmitType.XModem || type == FileTransmitType.XModem_1K)
         {
             if (_fileTransmit != null && _fileTransmit is XmodemHelper)
             {
                 ((XmodemHelper)_fileTransmit).XModemType = type;
             }
             else
             {
                 _fileTransmit = new XmodemHelper(this, type);
                 //_fileTransmit.LoggerEvent += OnLoggerEvent;
             }
             result = await _fileTransmit.SendFile(fileName, retryCount, sendProgress, token);
         }
         return result;
     }
     throw new ArgumentNullException("文件名不能为空");
 }

wpf不卡顿界面调用使用

 /// <summary>
        /// 开始测试并保存数据
        /// </summary>
        public void saveDataTest()
        {
            //string message = null;
            //bool processTest = false;
            if (PhaseShifterSN == null || DipAngleTest == null || PortNumbers == 0 || StatusFile==null)
            {
                MessageBox.Show("请检查移相器序列号,校准状态文件,移相器端口数,移相器测试倾角为空");
                return;
            }
            string s2pPath = "D:\\PhaseShifterTest\\"+ PhaseShifterSN+"\\" + DipAngleTest + "\\";
            if (instrs == null)
            {
                MessageBox.Show("请连接矢网");
                return;
            }
            //else
            //{
            //    processTest = true;
            //}
            Task.Run(async () =>
            {
                return await StartTest(s2pPath);
            }).GetAwaiter().OnCompleted(() => { });
            
        }

        private async Task<bool> StartTest(string s2pPath)
        {
            int number = 0;
            string message = null;
            SaveDataEnabled = false;
            RaceSwitch raceSw = new RaceSwitch();
            if (raceSw.Connect(false, out message))
            {
                
                ResultInstrument = message;
                instrs.LoadCSA(StatusFile);
                for (int i = 1; i < PortNumbers; i++)
                {
                    number = i + 1;
                    if (raceSw.Select_Switch_port(1, number, 50, out message, false))
                    {
                        Application.Current.Dispatcher.Invoke(new Action(() =>
                        {
                            ResultInstrument = message;
                        }));

                        Thread.Sleep(2000);
                        string path = s2pPath + DipAngleTest + "_" + i + ".S2P";
                        if (!instrs.SaveS2P(path, out message))
                        {
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                ResultInstrument = message;
                                MessageBox.Show(s2pPath + ",保存失败," + message, "提示");
                                SaveDataEnabled = true;
                            }));
                            return await Task.FromResult(true);
                        }
                    }
                    else
                    {
                        Application.Current.Dispatcher.Invoke(new Action(() =>
                        {
                            MessageBox.Show("开关切换失败,\r\n" + "端口1" + ",端口" + number + "\r\n是否重新切换", "提示");
                            SaveDataEnabled = true;
                        }));
                        
                        return await Task.FromResult(true); ;
                    }

                }
            }
            else
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    MessageBox.Show("矩阵开关连接失败," + message);
                    SaveDataEnabled = true;
                }));
                
                
            }
            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                MessageBox.Show("保存成功");
                PhaseShifterSN = "";
                PortNumbers = 0;
                DipAngleTest = "";
                SaveDataEnabled = true;
            }));
            
            return await Task.FromResult(true);
        }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WPF,UI元素的更新只能在UI线程上进行,这意味着如果我们在其他线程上进行数据操作,然后再尝试更新UI元素,会出现异常或者UI不会立即更新的情况。 要在WPF实现线程安全的UI更新,可以使用Dispatcher类。Dispatcher类可以让我们将操作在UI线程上执行,即使我们是在其他线程上调用的。 首先,我们需要获取到当前UI元素所在的Dispatcher对象,可以通过UI元素的Dispatcher属性来获取。然后,我们可以使用Dispatcher对象的Invoke或BeginInvoke方法将操作委托给UI线程执行。 例如,如果我们有一个DataGrid控件需要更新,我们可以首先获取DataGrid控件的Dispatcher对象,并在其他线程上进行数据操作后,使用Dispatcher对象的Invoke方法来更新DataGrid控件的数据源。 示例代码如下: ```csharp // 获取DataGrid的Dispatcher对象 var dispatcher = dataGrid.Dispatcher; // 在其他线程上进行数据操作 Task.Run(() => { // 模拟一些数据操作 Thread.Sleep(1000); // 更新DataGrid数据源 var newData = GetData(); // 通过Dispatcher对象的Invoke方法,在UI线程更新DataGrid数据源 dispatcher.Invoke(() => { dataGrid.ItemsSource = newData; }); }); ``` 在这个示例,我们使用了Task.Run()方法来模拟在其他线程上进行数据操作,然后通过Dispatcher对象的Invoke方法,在UI线程更新DataGrid控件的数据源。 通过使用Dispatcher类,我们可以确保在任何线程上进行的UI更新操作都会在UI线程上执行,保证了数据操作和UI更新线程安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值