19

I am currently working on a project in C#. I have a method called updateProgress() which has two int parameters (count and totalRows).

If I have call the method by saying updateProgress(count, totalRows) this works fine but I want to run this method within a new thread.

How can I go about doing this, I have looked online and everything looks overly complicated for what I am wanting to do.

Thanks for your help with this

1
  • 2
    Don't update the UI from a worker thread. Commented Nov 14, 2010 at 19:28

6 Answers 6

36

Something like this:

new Thread(delegate () {
    updateProgress(count, totalRows);
}).Start();
Sign up to request clarification or add additional context in comments.

2 Comments

Tried Thread t = new Thread(new ParameterizedThreadStart(method)); t.Start(parameter); but that didn't work. Your snippet here did though. Thanks
@Ortund Does method have the signature void method(object), or is the parameter of some other type?
7

Be aware that threading actually is quite a complex topic, so if you have troubles understanding the asynchronous APIs available in the .NET Framework, I doubt if you should start using threads in the first place.

Anyway, you have several options:

  • Spin off a thread by your own (like cdhowie pointed out), which is rather discouraged.

  • Use the TPL (task parallel library) if you are running on .NET 4. Here is a good introduction. TaskFactory.StartNew(() => updateProgress(count, totalRows));

  • Use the ThreadPool if you are running on an older version of .NET. ThreadPool.QueueUserWorkItem(s => updateProgress(count, totalRows));

Of course there are other ways too, but this are imo the most important ones.

Best Regards,
Oliver Hanappi

Comments

4

This has been almost a year, and my answer will not add anything "new" to what has already been said in other answers.

If someone is using .Net 4.0 or higher, best options would be to use a task and let the framework decide the best, by calling TaskFactory.StartNew(...). For older versions, still it's better to utilize the thread pool by using ThreadPool.QueueUserWorkItem(...).

Now, if still someone wants to use the thread in the basic way (creating new thread) for some reason, then this

new Thread(delegate () {
    updateProgress(count, totalRows);
}).Start();

can be written in a little cleaner way, using the lambda expression, like this

new Thread(() => updateProgress(count, totalRows)).Start();

Comments

1

There are different ways to run a method in a different thread, like Thread, BackgroundWorker, ThreadPool or Task. Which one to choose depends of various things.

From the name of the method, it sounds like the method should show some progress in the GUI of your application. If that's the case, you have to run the method on the GUI thread. If you want to call it from another thread, you have to use Dispatcher.Invoke() in WPF and Control.Invoke() in WinForms.

Comments

0

try following

ThreadPool.QueueUserWorkItem((o) => { updateProgress(5, 6); });

Comments

0

Here's a more complex example without anonymous delegates. Look at result in the completed function.

using System;
using System.Threading;
using System.ComponentModel;

class Program
{
  static BackgroundWorker _bw;

  static void Main()
  {
    _bw = new BackgroundWorker
    {
      WorkerReportsProgress = true,
      WorkerSupportsCancellation = true
    };
    _bw.DoWork += bw_DoWork;
    _bw.ProgressChanged += bw_ProgressChanged;
    _bw.RunWorkerCompleted += bw_RunWorkerCompleted;

    _bw.RunWorkerAsync ("Hello to worker");

    Console.WriteLine ("Press Enter in the next 5 seconds to cancel");
    Console.ReadLine();
    if (_bw.IsBusy) _bw.CancelAsync();
    Console.ReadLine();
  }

  static void bw_DoWork (object sender, DoWorkEventArgs e)
  {
    for (int i = 0; i <= 100; i += 20)
    {
      if (_bw.CancellationPending) { e.Cancel = true; return; }
      _bw.ReportProgress (i);
      Thread.Sleep (1000);      // Just for the demo... don't go sleeping
    }                           // for real in pooled threads!

    e.Result = 123;    // This gets passed to RunWorkerCompleted
  }

  static void bw_RunWorkerCompleted (object sender,
                                     RunWorkerCompletedEventArgs e)
  {
    if (e.Cancelled)
      Console.WriteLine ("You canceled!");
    else if (e.Error != null)
      Console.WriteLine ("Worker exception: " + e.Error.ToString());
    else
      Console.WriteLine ("Complete: " + e.Result);      // from DoWork
  }

  static void bw_ProgressChanged (object sender,
                                  ProgressChangedEventArgs e)
  {
    Console.WriteLine ("Reached " + e.ProgressPercentage + "%");
  }
}

3 Comments

What do you mean by "... without delegates"? I see several implicit method group conversions in your code.
It uses functions instead of inline delegates. Sometimes they are easier to work with and read particularly for novice thread users.
Then I think you should clarify by saying "without anonymous delegates." Otherwise, the OP may completely miss the fact that a ProgressChangedEventHandler delegate instance is being created, for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.