TheBigBearNow Ответов: 2

Как вызвать поток делегатов


Всем привет,
Я пытаюсь использовать backgroundworker и хочу вызвать делегат, чтобы заставить мой loadingspinner работать во время выполнения запроса.
Как бы я это сделал?
Вот код у меня есть?
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;
        }


Пожалуйста, помогите мне изменить это, чтобы использовать это правильно с вызовом вместо того, чтобы я использовал поток.sleep()

Что я уже пробовал:

Используя поток backgroundworker, но используя thread.sleep для моего loadingspinner, я хочу вызвать делегат вместо этого, например
Application.Current.Dispatcher.Invoke(delegate
    {
        backgroundWorker.ReportProgress(); //but what do i pass in and not sure if this is it
    });

2 Ответов

Рейтинг:
1

OriginalGriff

Сделайте это наоборот: отобразите счетчик - и управляйте им - из основного потока пользовательского интерфейса, а также используйте события BackgroundWorker для мониторинга прогресса и завершения работы. Длинная работа выполняется в BackgroundWorker, пользовательский интерфейс в потоке пользовательского интерфейса. Таким образом, нет никакой необходимости призывать что-либо!
(Это именно то, для чего существует класс BackgroundWorker: события отчета о ходе выполнения и завершения запускаются в исходном потоке (UI), поэтому нет необходимости вызывать).


Рейтинг:
0

Graeme_Grant

Пользовательский интерфейс выполняется в основном потоке, поэтому вы не можете получить доступ к пользовательскому интерфейсу из другого потока. Итак у вас есть флаг который прядильщик Visibility привязывается к использованию привязки данных, скажем, называется IsBusy Затем вы связываетесь с пользовательским интерфейсом через флаг. Во-вторых, как упоминал OriginalGriff, вы затем выгружаете длительную задачу в другой поток. Вам нужно будет почитать дальше Привязка данных (WPF | Microsoft Docs)[^] если вы незнакомы.