Home > Mobile >  Due to the use of Dispatcher,t he window still locks
Due to the use of Dispatcher,t he window still locks

Time:10-04

I have a program similar to chatbot in Wpf. I have a stack where I create the user controls I have and enter them. I have to use Net3.5 . The response from the server is delayed. The problem I have is when I type and send the textbox the server does not answer, I can not type another question and the window is locked. Did I use Dispatcher correctly?

chatbot

 private void send_Click(object sender, RoutedEventArgs e)
    {

        stack.Children.Add(new UserControl_Send()
        {
            DataSend = txt_input.Text,
            DateTimeBot = DateTime.Now.ToString("HH:mm")
        });

        DispatchFit();

    }

    private void DispatchFit()
    {
        Dispatcher.BeginInvoke(new Action(ResponsServer), DispatcherPriority.Background);
    }
    public void ResponsServer()
    {
        Thread.Sleep(3000);
        stack.Children.Add(new UserControl_Receive()
        {
            DataRecive = get(txt_input.Text),
            DateTimeBot = DateTime.Now.ToString("HH:mm"),
        });
    }

CodePudding user response:

When that ResponsServer() callback is being processed on your UI thread, then that Sleep is elongating the amount of time that callback is taking to process (Sleep does not pump the UI's dispatcher message queue).

If you want your callback to be done after 3 seconds, then you need to use a timer, or you can use "async" to cause a delayed processing of your callback.

Look at this question: Delayed Dispatch Invoke?

Or use this to have a BackgroundWorker do the delay and then call your ResponsServer on the UI thread (not the best code as it creates a new BackgroundWorker each time).

https://www.codeproject.com/Tips/240274/Execute-later-for-delayed-action

CodePudding user response:

You are a little confused about the methods. If I understand correctly, then Slip is an emulation of the delay in the execution of sending a message to the server.

Then you need something like:

    private async void send_ClickAsync(object sender, RoutedEventArgs e)
    {

        stack.Children.Add(new UserControl_Send()
        {
            DataSend = txt_input.Text,
            DateTimeBot = DateTime.Now.ToString("HH:mm")
        });

        await ResponsServerAsync();

        stack.Children.Add(new UserControl_Receive()
        {
            DataRecive = get(txt_input.Text),
            DateTimeBot = DateTime.Now.ToString("HH:mm"),
        });
    }

    public async Task ResponsServerAsync()
    {
        Thread.Sleep(3000);
    }

For .Net Framework 3.5

        private void send_Click(object sender, RoutedEventArgs e)
        {

            stack.Children.Add(new UserControl_Send()
            {
                DataSend = txt_input.Text,
                DateTimeBot = DateTime.Now.ToString("HH:mm")
            });

            Thread thread = new Thread(ResponsServer);
            thread.Start();

        }

        public void ResponsServer()
        {
            Thread.Sleep(3000);
            if (Dispatcher.CheckAccess())
            {
                StackChildrenAdd();
            }
            else
            {
                Dispatcher.InvokeAsync(StackChildrenAdd);
            }
    
        }
        private void StackChildrenAdd()
        {
            stack.Children.Add(new UserControl_Receive()
            {
                DataRecive = get(txt_input.Text),
                DateTimeBot = DateTime.Now.ToString("HH:mm"),
            });
        }
  • Related