Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
* * * * * 1 votes

Some Techniques For Faster Application


  • Please log in to reply
3 replies to this topic

#1 Tonchi

Tonchi

    Helping the world with programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1249 posts
  • Location:Zagreb
  • Programming Language:C#, Others
  • Learning:C, C++, Python, JavaScript, Transact-SQL, Assembly

Posted 24 June 2012 - 07:50 AM

I want to make my program "faster" for the user. What I mean is that I want to make that user don't see any freezing scenes on application. For example, user wants to save something in database by clicking the button for saving. If user input is a long text, he can wait for a few seconds (depends on how strong is his computer) for data to be stored in database. During that process he will think that application sucks because it's having a lag. What I want is to make a progress bar that will be loading depending on how fast will data be stored in a database. I have a very little experience with progressBar control and a very little experience with Threading so I will be very thankful if someone give me an example for my problem. It is very important to be written for WPF apps because WPF controls are not the same as WinForms controls. Thank you
  • 0

Microsoft Student Partner, Microsoft Certified Professional


#2 Davide

Davide

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 484 posts

Posted 24 June 2012 - 12:56 PM

Create a separate thread to do your work so that the user interface doesn't freeze.

//Assume this gets executed upon clicking a button
Thread myThread = new Thread(method);
myThread.Start();

//And this is the method that gets called and run in a separate thread 
//when you do myThread.Start()
public method( ... something usually goes here )
{
   //...
}

  • 0
Are you a newbie programmer trying to learn C#? Check out my small tutorial: Visual C# Programming Basics

#3 Yonatan

Yonatan

    CC Regular

  • Member
  • PipPipPip
  • 37 posts
  • Location:Israel
  • Programming Language:C, Java, C++, C#, JavaScript, PL/SQL, Visual Basic .NET
  • Learning:Python, JavaScript

Posted 24 June 2012 - 01:01 PM

If I may, I would like to ask how can you make a progress bar according to a thread progress in a case similar to this.
  • 0

#4 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 24 June 2012 - 07:44 PM

Well, the general concept is that you should run your long-running task in a thread as GUI can only be updated in main-thread. If you follow this, your GUI will not be like in frozen situation.

There are 4 ways to perform long running in on thread.
  • System.Timers.Timer class.
    class ThreadUser1	
    {	
        private System.Timers.Timer _timer;	
    	
        public ThreadUser1()	
        {	
            _timer = new System.Timers.Timer();	
            _timer.Interval = 1000; // 1 second	
            _timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimerElapsedEvent);	
            _timer.Enabled = true;	
        }	
    	
        private void OnTimerElapsedEvent(object source, System.Timers.ElapsedEventArgs e)	
        {	
            // This method will be hitted in another thread.	
            Console.WriteLine(e.SignalTime.ToString("F"));	
        }	}
  • System.Threading.ThreadPool.QueueUserWorkItem method.
    class ThreadUser2	
    {	
        public ThreadUser2()	
        {	
            System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(OnThreadPoolThreadHit));	
        }	
    	
        private void OnThreadPoolThreadHit(Object stateInfo)	
        {	
            // This method will be hitted in another thread.	
            Console.WriteLine("Get called from thread pool thread");	
        }	}
  • System.Threading.Thread class
    class ThreadUser3	
    {	
        private System.Threading.Thread _thread;	
    	
        public ThreadUser3()	
        {	
            _thread = new System.Threading.Thread(new System.Threading.ThreadStart(OnThreadHit));	
            _thread.Start();	
        }	
    	
        private void OnThreadHit()	
        {	
            // This method will be hitted in another thread.	
            Console.WriteLine("Get called from a user thread using System.Threading.Thread class");	
        }	}
  • System.ComponentModel.BackgroundWorker class
    class ThreadUser4	
    {	
        private System.ComponentModel.BackgroundWorker _worker;	
    	
        public ThreadUser4()	
        {	
            _worker = new System.ComponentModel.BackgroundWorker();	
            _worker.WorkerReportsProgress = true;	
            _worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(OnProgressChanged);	
            _worker.DoWork += new System.ComponentModel.DoWorkEventHandler(OnDoWork);	
            _worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(OnRunWorkerCompleted);	
            _worker.RunWorkerAsync("This is a argument");	
        }	
    	
        private void OnProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)	
        {	
            Console.WriteLine(String.Format("BackgroundWorker Progress: {0}", e.ProgressPercentage));	
        }	
    	
    	
        private void OnDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)	
        {	
            (sender as System.ComponentModel.BackgroundWorker).ReportProgress(0);	
            (sender as System.ComponentModel.BackgroundWorker).ReportProgress(25);	
            Console.WriteLine("Get called from a user thread using System.Threading.Thread class");	
            (sender as System.ComponentModel.BackgroundWorker).ReportProgress(75);	
            (sender as System.ComponentModel.BackgroundWorker).ReportProgress(100);	
            e.Result = "This is the result";	
        }	
    	
        void OnRunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)	
        {	
            Console.WriteLine(String.Format("BackgroundWorker finished. Result = {0}", e.Result.ToString()));	
        }    	}

Note that, you can update GUI only in main thread. So, in all the 4 cases you can use any of Control.Invoke (synchronous), BeginInvoke-EndInvoke (asynchronous) pair of Control class to update your GUI from non-main threads. However if you use BackgroundWorker, you can use ReportProgress method with ProgressChanged event to update your GUI. Note that, ProgressChanged and RunWorkerCompleted event handlers are get called in main-thread. As example, We have used the above code for BackgroundWorker in a Windows-Form app following. There is a progress-bar which will be updated in the ProgressChanged and RunWorkerCompleted event handlers. We used ReportProgress method of BackgroundWorker to report the progress so that ProgressChanged event is fired in main thread.

class FormBWWithProgressBar: Form
{
    private System.ComponentModel.BackgroundWorker _worker;
    ProgressBar _progressBar = new ProgressBar();

    public Form4()
    {
        Text = "BackgroundWorker with ProgressBar";

        _worker = new System.ComponentModel.BackgroundWorker();
        _worker.WorkerReportsProgress = true;
        _worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(OnProgressChanged);
        _worker.DoWork += new System.ComponentModel.DoWorkEventHandler(OnDoWork);
        _worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(OnRunWorkerCompleted);
        _worker.RunWorkerAsync("This is a argument");

        this._progressBar.Location = new System.Drawing.Point(45, 110);
        this._progressBar.Size = new System.Drawing.Size(197, 23);
        this.Controls.Add(_progressBar);
    }


    private void OnProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
    {
        Console.WriteLine(String.Format("BackgroundWorker Progress: {0}", e.ProgressPercentage));
        _progressBar.Value = e.ProgressPercentage;
    }


    private void OnDoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        (sender as System.ComponentModel.BackgroundWorker).ReportProgress(0);
        System.Threading.Thread.Sleep(1000);
        (sender as System.ComponentModel.BackgroundWorker).ReportProgress(25);
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine("Get called from a user thread using System.Threading.Thread class");
        (sender as System.ComponentModel.BackgroundWorker).ReportProgress(75);
        System.Threading.Thread.Sleep(1000);
        (sender as System.ComponentModel.BackgroundWorker).ReportProgress(100);
        e.Result = "This is the result";
    }

    void OnRunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine(String.Format("BackgroundWorker finished. Result = {0}", e.Result.ToString()));
        _progressBar.Value = 0;
    }
}

  • 1




Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download