如何调用委托线程 [英] How to I invoke a delegate thread

查看:63
本文介绍了如何调用委托线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在尝试使用backgroundworker,我想调用一个委托让我的loadingspinner在我运行查询时运行。

如何我会这样做吗?

这是我的代码?

Hello all,
I am trying to use a backgroundworker and I want to invoke a delegate to get my loadingspinner to run while I am running a query.
How would I do this?
Here is code I have?

public LoginScreen()
        {
            InitializeComponent();
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);            
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
        }
        private void BtnLoginUser_Click(object sender, RoutedEventArgs e)
        {
//Not sure where I start my backgroundworker and invoke delegate
if (valid)
                {
                    // Start the background worker.
                    backgroundWorker.RunWorkerAsync();
                }
            }
        }
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {   //Sometimes loading happens so fast so introduce 5 sec thread.sleep()
            for(int i = 1; i <= 10; i++)
            {
                System.Threading.Thread.Sleep(500);
                backgroundWorker.ReportProgress(i);
            }
        }
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {   //Start the .Gif (Play and make visible)    free to interact with UI in progressChanged. 
            LoadSpinner.Play();
            LoadSpinner.Visibility = Visibility.Visible;
            try
            {
                loginUser = SQLuserAccess.UserLogin(username, password);
                if (loginUser != null)
                {
                    if (username == loginUser.Username && password == loginUser.Password)
                    { }
                    else
                        lblInvalidText.Visibility = Visibility.Visible;
                }
                else
                    lblInvalidText.Visibility = Visibility.Visible;
            }
            catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); }
        }
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Stop the loading  RUNS when thread is COMPLETED can work on UI
            BtnCreateUser.Content = "Register";
            BtnLoginUser.IsEnabled = true;
            LoadSpinner.Visibility = Visibility.Hidden;
            LoadSpinner.Stop();
            LoadSpinner.Close();
            if (loginUser != null)
            {
                if (loginUser.IsAdmin)
                {
                    Window WindowAdminMenu = new AdminWindow(loginUser);
                    WindowAdminMenu.Show();
                    Close();
                }
                else if (loginUser.IsCustomer)
                {
                    Window WindowCustomerMenu = new CustomerScreen(loginUser);
                    WindowCustomerMenu.Show();
                    Close();
                }
                else
                    lblInvalidText.Content = "Invalid Account Information";
            }
            else
                lblInvalidText.Visibility = Visibility.Visible;
        }





请帮我修改一下,使用正确的方式调用而不是使用thread.sleep( )



我尝试了什么:



使用backgroundworker线程但是使用thread.sleep为我的loadingspinner我想调用委托代替



Please help me change this to use this the correct way with invoking instead of me using a thread.sleep()

What I have tried:

Using a backgroundworker thread but using thread.sleep for my loadingspinner I want to invokea delegate instead like

Application.Current.Dispatcher.Invoke(delegate
    {
        backgroundWorker.ReportProgress(); //but what do i pass in and not sure if this is it
    });

推荐答案

反过来做:显示微调器 - 并从主UI线程控制它 - 并使用BackgroundWorker事件来监视进度和终止。漫长的工作在BackgroundWorker中完成,即UI线程中的UI。这样,就没有必要调用任何东西了!

(这正是BackgroundWorker类的用途:进度报告和终止事件在原始(UI)线程上触发,因此不需要for Invoke)。
Do it the other way round: display the spinner - and control it - from the main UI thread, and use the BackgroundWorker events to monitor progress and termination. The long job gets done in the BackgroundWorker, the UI in the UI thread. That way, there is no need to invoke anything!
(That's exactly what the BackgroundWorker class is there for: the progress reporting and termination events are fired on the original (UI) thread so there is no need for Invoke).


UI在主线程中运行,因此您无法从其他线程访问UI。所以你有一个标志,Spinner Visibility 绑定使用数据绑定,比如称为 IsBusy 。然后通过标志与UI进行通信。其次,正如OriginalGriff所提到的那样,然后将长时间运行的任务卸载到另一个线程。您需要阅读数据绑定(WPF | Microsoft Docs) [ ^ ]如果您不熟悉。
The UI runs in the main thread, so you can't access the UI from a different thread. So you have a flag that the Spinner Visibility is bound to using data binding, say is called IsBusy. Then you communicate to the UI via the flag. Secondly, as OriginalGriff mentioned, you then offload the long-running task to a different thread. You will need to read up on Data Binding (WPF | Microsoft Docs)[^] if you are unfamiliar.


这篇关于如何调用委托线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆