none
WPF BackgroundWorker blocked application RRS feed

  • Question

  • Hello,
    I have a WPF application and a BackgroundThread / BackgroundWorker.
    I press the button, the
    MessageBox.Show("Ready");
    appears,
       then is blocked the UserInterface.
      
       That's exactly what I'm trying to avoid with this thread.
      
     How can I solve it?  FTP Uploader
     
    Do I have to bring in the dispatcher?
    If yes, how and why?
    My code.  
    Thanks in advance for tipps.
    With best regards Markus
    namespace FTPTest
    {
        /// <summary>
        /// Interaktionslogik für MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            FTPUpload MyFTP;
            public MainWindow()
            {
                InitializeComponent();
    
                MyFTP = new FTPUpload();
            }
    
            private void Start(object sender, RoutedEventArgs e)
            {
                //MyFTP.UploadFiles();
                // Dispatcher.Invoke((Action)(() => MyFTP.UploadFolder()));
    
                MyFTP.UploadFolder();
                MessageBox.Show("Ready");
            }
    
            private void Cancel(object sender, RoutedEventArgs e)
            {
                MyFTP.Cancel();
            }
        }
    }
    
    // ----
    
    public FTPUpload()
    {
    	BackgroundWorkerFTP = new BackgroundWorker();
    	BackgroundWorkerFTP.DoWork += BackgroundWorkerFTP_DoWork;
    	BackgroundWorkerFTP.ProgressChanged += BackgroundWorkerFTP_ProgressChanged;
    	BackgroundWorkerFTP.RunWorkerCompleted += BackgroundWorkerFTP_RunWorkerCompleted;
    	BackgroundWorkerFTP.WorkerReportsProgress = true;
    	BackgroundWorkerFTP.WorkerSupportsCancellation = true;
    
    	InputParameter.Username = "XXXXX";
    	InputParameter.Password = "YYYYYYYY";
    	InputParameter.Server = "ftp://ftp.test.de"; // "127.0.0.1";
    }
    
    public void UploadFolder()
    {
    	InputParameter.UploadFolder = "C:\\Temp";
    	InputParameter.CurrentUploadFile = "";
    
    	if (BackgroundWorkerFTP.IsBusy != true)
    	{
    		// Start the asynchronous operation.  
    		BackgroundWorkerFTP.RunWorkerAsync(InputParameter);
    	}
    }
    
    
    private void BackgroundWorkerFTP_DoWork(object sender, DoWorkEventArgs e)
    {
    	//Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
    	//{
    	// FTPUpload bwSender = (FTPUpload)sender;
    	//BackgroundWorker bw = (BackgroundWorker)sender;
    	//System.Diagnostics.Debug.Assert(this == bw);
    
    	var w = sender as BackgroundWorker;
    
    	string fileName = ((FtpSetting)e.Argument).FileName;
    	string fullName = ((FtpSetting)e.Argument).FullName;
    
    
    	string userName = ((FtpSetting)e.Argument).Username;
    	string password = ((FtpSetting)e.Argument).Password;
    	string server = ((FtpSetting)e.Argument).Server;
    	string uploadFolder = ((FtpSetting)e.Argument).UploadFolder;
    
    
    
    	string[] files = Directory.GetFiles(uploadFolder);
    	for (int iFile = 0; iFile < files.Length; iFile++)
    	{
    		if (!BackgroundWorkerFTP.CancellationPending)
    		{
    			FileInfo fi = new FileInfo(files[iFile]);
    
    			Application.Current.Dispatcher.Invoke((Action)(() =>
    			{
    
    				FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fi.Name)));
    				request.Method = WebRequestMethods.Ftp.UploadFile;
    				request.Credentials = new NetworkCredential(userName, password);
    				request.Proxy = null;
    				Stream ftpStream = request.GetRequestStream();
    				FileStream fs = File.OpenRead(fi.FullName);
    				byte[] buffer = new byte[1024];
    				double total = (double)fs.Length;
    				int byteRead = 0;
    				double read = 0;
    
    				do
    				{
    					if (!BackgroundWorkerFTP.CancellationPending)
    					{
    						//Upload file & update process bar
    						byteRead = fs.Read(buffer, 0, 1024);
    						ftpStream.Write(buffer, 0, byteRead);
    						read += (double)byteRead;
    						double percentage = read / total * 100;
    
    						// bwSender.CurrentUploadFile = fi.FullName;
    						BackgroundWorkerFTP.ReportProgress((int)percentage, fi.FullName);
    					}
    				}
    				while (byteRead != 0);
    
    				// Using RunWorkerCompleted
    				e.Result = files.Length;
    
    				fs.Close();
    				ftpStream.Close();
    			
    			}));
    		}
    		else
    			break;
    	}
    	//}));
    }



    • Edited by Markus Freitag Friday, August 16, 2019 4:35 PM
    • Moved by CoolDadTx Friday, August 16, 2019 8:40 PM WPF related
    Friday, August 16, 2019 4:33 PM

Answers

  • Hi  Markus,    

    >>It's not obvious when I need invoke, dispatcher makes things complicated.

    I would like to display the uploaded file names in the Mainform.

    Thanks for more tips in advance. Many greetings Markus


    You can use the ReportProgress(int percentProgress, object userState) method(The ProgressChanged event is raised on the UI thread, not the worker thread) to report the file name. 

          // bwSender.CurrentUploadFile = fi.FullName;
           BackgroundWorkerFTP.ReportProgress((int)percentage, fi.FullName);

     You can pass the file name collection as the object userState parameter. Then, read it and show on the Mainform.

          void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                label1.Content = "Progress: " + e.ProgressPercentage + "; File: " + e.UserState;
               
            }
    
    Besides, It would be appreciated if you could close the thread by marking helpful posts as an answer. This will help other members to find the solution quickly if they have faced the similar issue. If you have a new question you can start a new thread  with all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages.
     

    Best regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Markus Freitag Wednesday, August 21, 2019 10:04 AM
    Wednesday, August 21, 2019 3:25 AM
    Moderator

All replies

  • Try removing Invoke. Execute the code directly. Use Invoke when you want to access a control or window.

    Friday, August 16, 2019 5:56 PM
  • Hello,

     private void Start(object sender, RoutedEventArgs e)
            {
                MyFTP.UploadFolder();
                MessageBox.Show("Ready");
            }

    Of course I did it without Invoke and Dispatcher. It did not work.

    I am looking for a solution. How to get it right? Can you publish an example?

    Thanks for tipps. Regards Markus

    Saturday, August 17, 2019 9:13 AM
  • Hello, I tried so, without dispatcher, invoke.
    Result the message box appears, can not be confirmed with ok. Only when the thread is finished.
    I need a solution. Do you know the solution?It does not have to be invoke, which resulted in a google search.
    Maybe it's a WPF issue related to BackgroundWorker?
    Thanks in advance for examples of solutions. Greetings Markus
    private void BackgroundWorkerFTP_DoWork(object sender, DoWorkEventArgs e) {
    	var w = sender as BackgroundWorker;
    	string fileName = ((FtpSetting)e.Argument).FileName;
    	string fullName = ((FtpSetting)e.Argument).FullName;
    
    	string userName = ((FtpSetting)e.Argument).Username;
    	string password = ((FtpSetting)e.Argument).Password;
    	string server = ((FtpSetting)e.Argument).Server;
    	string uploadFolder = ((FtpSetting)e.Argument).UploadFolder;
    
    	string[] files = Directory.GetFiles(uploadFolder);
    	for (int iFile = 0; iFile < files.Length; iFile++)
    	{
    		if (!BackgroundWorkerFTP.CancellationPending)
    		{
    			FileInfo fi = new FileInfo(files[iFile]);
    			FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fi.Name)));
    			request.Method = WebRequestMethods.Ftp.UploadFile;
    			request.Credentials = new NetworkCredential(userName, password);
    			request.Proxy = null;
    			Stream ftpStream = request.GetRequestStream();
    			FileStream fs = File.OpenRead(fi.FullName);
    			byte[] buffer = new byte[1024];
    			double total = (double)fs.Length;
    			int byteRead = 0;
    			double read = 0;
    			do
    			{
    				if (!BackgroundWorkerFTP.CancellationPending)
    				{
    					//Upload file & update process bar
    					byteRead = fs.Read(buffer, 0, 1024);
    					ftpStream.Write(buffer, 0, byteRead);
    					read += (double)byteRead;
    					double percentage = read / total * 100;
    
    					// bwSender.CurrentUploadFile = fi.FullName;
    					BackgroundWorkerFTP.ReportProgress((int)percentage, fi.FullName);
    				}
    			}
    			while (byteRead != 0);
    
    			// Using RunWorkerCompleted
    			e.Result = files.Length;
    
    			fs.Close();
    			ftpStream.Close();
    			break;
    	}
    }



    Monday, August 19, 2019 3:31 PM
  • Hi     Markus Freitag,

    >>Result the message box appears, can not be confirmed with ok. Only when the thread is finished.

    Where do you show the message box? As my understanding, you need to show message box in the ProgressChanged or RunWorkerCompleted.
     
    WPF BackgroundWorker blocked application:


    Best regards

    Yong Lu

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, August 20, 2019 6:52 AM
    Moderator
  • Hello Young Lu,

    >Where do you show the message box? As my understanding, you need

    >to show message box in the ProgressChanged or RunWorkerCompleted.

    I show the messagebox in the main form.

     private void Start(object sender, RoutedEventArgs e)
            {
                MyFTP.UploadFolder();
                MessageBox.Show("Ready");
            }
    private void Bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    MessageBox.Show("Task completed");
    }
    That is helpful. If I now have text fields in the form (WPF), must fill them depending on the thread, must show, how would I implement that?

    It's not obvious when I need invoke, dispatcher makes things complicated.

    I would like to display the uploaded file names in the Mainform.

    Thanks for more tips in advance. Many greetings Markus

    Tuesday, August 20, 2019 10:22 AM
  • Hi  Markus,    

    >>It's not obvious when I need invoke, dispatcher makes things complicated.

    I would like to display the uploaded file names in the Mainform.

    Thanks for more tips in advance. Many greetings Markus


    You can use the ReportProgress(int percentProgress, object userState) method(The ProgressChanged event is raised on the UI thread, not the worker thread) to report the file name. 

          // bwSender.CurrentUploadFile = fi.FullName;
           BackgroundWorkerFTP.ReportProgress((int)percentage, fi.FullName);

     You can pass the file name collection as the object userState parameter. Then, read it and show on the Mainform.

          void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                label1.Content = "Progress: " + e.ProgressPercentage + "; File: " + e.UserState;
               
            }
    
    Besides, It would be appreciated if you could close the thread by marking helpful posts as an answer. This will help other members to find the solution quickly if they have faced the similar issue. If you have a new question you can start a new thread  with all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages.
     

    Best regards

    Yong Lu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Markus Freitag Wednesday, August 21, 2019 10:04 AM
    Wednesday, August 21, 2019 3:25 AM
    Moderator