c#中从按钮或定时器实例化时的不同行为

本文关键字:实例化 按钮 定时器 | 更新日期: 2023-09-27 18:15:05

我有一个名为getMessages的函数,可以通过按钮点击调用(使用RelayCommand触发器),或者每隔15秒在计时器中调用。

期望的行为是:

webservice> deserialize answer> system notification> updatelistview> insert localDB

但是当定时器调用该函数时,updatelistview没有完成。如果功能相同并且在按钮命令中完美工作,为什么会发生这种情况?

代码:

 // Get messages for the logged in user
    public async void getMessages()
    {
        try
        {
            List<FriendGetMessage> msg = new List<FriendGetMessage>();
            var response = await CommunicationWebServices.GetCHAT("users/" + au.idUser + "/get", au.token);
            if (response.StatusCode == HttpStatusCode.OK) // If there are messages for me.
            {
                var aux = await response.Content.ReadAsStringAsync();
                IEnumerable<FriendGetMessage> result = JsonConvert.DeserializeObject<IEnumerable<FriendGetMessage>>(aux);
                if (result != null)
                {
                    foreach (var m in result)
                    {
                        msg.Add(m);
                    }
                    //MsgList=msg;
                    foreach (var f in Friends)
                    {
                        if (f.msg == null || f.msg.Count() == 0)
                        {
                            f.msg = new ObservableCollection<Messages>();
                        }
                        foreach (var mess in msg)
                        {
                            if (mess.idUser == f.idUser)
                            {
                                Messages mm = new Messages();
                                mm.received = mess.message;
                                mm.timestamp = "Received " + mess.serverTimestamp;
                                mm.align = "Right";
                                // Add to the friend list.
                                f.msg.Add(mm);
                                // Add to Local DB
                                InsertMessage(null, au.idUser.ToString(), f.idUser, mess.message, mess.serverTimestamp);
                                var notification = new System.Windows.Forms.NotifyIcon()
                                {
                                    Visible = true,
                                    Icon = System.Drawing.SystemIcons.Information,
                                    BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info,
                                    BalloonTipTitle = "New Message from " + f.name,
                                    BalloonTipText = "Message: " + mess.message,
                                };
                                // Display for 5 seconds.
                                notification.ShowBalloonTip(5);
                                // The notification should be disposed when you don't need it anymore,
                                // but doing so will immediately close the balloon if it's visible.
                                notification.Dispose();
                            }
                        }
                    }
                    counterChat = 1; // resets the counter  
                }
            }
            else {
                counterChat = counterChat * 2;
            }
            //var sql = "select * from chat";
            //var respo = GetFromDatabase(sql);
            OnPropertyChanged("Friends");
        }
        catch (Exception e)
        {
            MessageBox.Show("GetMessages: " + e);
            Debug.WriteLine("{0} Exception caught.", e);
        }
    }

代码定时器:

public void chatUpdate()
    {
        _timerChat = new DispatcherTimer(DispatcherPriority.Render);
        _timerChat.Interval = TimeSpan.FromSeconds(15);
        _timerChat.Tick += new EventHandler(timerchat_Tick);
        _timerChat.Start();
    }
    public void timerchat_Tick(object sender, EventArgs e)
    {
        if (counterChat != incChat)
        {
            incChat++;
        }
        else
        {
            getMessages();
            OnPropertyChanged("Friends");
            incChat = 0;
        }
    }

添加-我也尝试过这个,没有工作(似乎是某种并发问题的ObservableCollection称为朋友(是一个friendslist)每个朋友有一个ObservableCollection的消息(是一个聊天))

public void chatUpdate()
    {
        _timerChat = new DispatcherTimer(DispatcherPriority.Render);
        _timerChat.Interval = TimeSpan.FromSeconds(15);
        _timerChat.Tick += new EventHandler(timerchat_Tick);
        _timerChat.Start();
    }
    public async void timerchat_Tick(object sender, EventArgs e)
    {
        if (counterChat != incChat)
        {
            incChat++;
        }
        else
        {
            Application.Current.Dispatcher.Invoke((Action)async delegate { await getMessages(); });
            incChat = 0;
        }
    }

问好,

c#中从按钮或定时器实例化时的不同行为

我认为你需要使定时器处理程序是一个异步方法如下:

public async void timerchat_Tick(object sender, EventArgs e)
{
    if (counterChat != incChat)
    {
        incChat++;
    }
    else
    {
        await getMessages();
        OnPropertyChanged("Friends");
        incChat = 0;
    }
}

这样OnPropertyChanged("Friends")保证在getMessages中的工作完成后触发。

方法需要更改为:

  DispatcherTimer _timerChat = new DispatcherTimer(DispatcherPriority.Render);
        _timerChat.Interval = TimeSpan.FromSeconds(15);
        _timerChat.Tick += new EventHandler(timerchat_Tick);
        _timerChat.Start();

    public async void timerchat_Tick(object sender, EventArgs e)
    {
//...
        await getMessages();
//...
    }
    public async Task getMessages()
    {
        try
        {
            // ... your code here
                string result = await response.Content.ReadAsStringAsync();
            // .... rest of your code
        }
        catch (Exception e)
        {
            MessageBox.Show("GetMessages: " + e);
        }
    }

问题解决了。问题是在我的ViewModels我打开多个线程,有时正确的一个会更新UI,有时没有。

谢谢大家的回答。