Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

c# - How to create and use background thread to change object from another thread

I have object in main thread. I need to create background thread, which will parse website permanently and change object from main thread each time background thread gets new data. What is the proper way to do that? Another question: how to create background thread which will work permanently?

I need smth like

static Main void() {
  Object VariableObject = new Object();
  //TODO: CreateBackgroundThread ();
  //TODO: DoForegroundWork();
}

...
CreateBackgroundThread void () {
  while (true) {
    Object NewData = new Object;
    //TODO: Get object from Main method and assign NewData object to it
  }
}

I hope I expressed clear. I suppose it's ordinary task for many projects, I just don't know how to do it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A background thread is scoped to the main thread. So it'll run as long as the console app is alive. .Net has a rich threading library, so I leave it up to you.

for ex) 1) use a delegate and call BeginInvoke 2) system.threading.Thread namespace 3) System.Threading.Tasks namespace

Since threading can be daunting, here's a sample console app that should do almost what you need.

run the app and once your comfy with the basics, you can write your own.

using System;
using System.Collections.Generic;
using System.Threading;

/// <summary>
/// Represent a hard working employee.
/// 
/// The employee will process a job, once it comes in.
/// 
/// 
/// </summary>
public class Employee
{
    private Queue<string> _tasksTray;
    private string _employeeID;

    public Employee(string employeeID, Queue<string> taskTray)
    {
        //employee's ID number.  
        this._employeeID = employeeID;

        //get a reference to the task tray
        this._tasksTray = taskTray;

        //fire up a worker thread
        var thread = new Thread(new ThreadStart(this.Run));
        thread.IsBackground = true;
        thread.Start();
    }

    private void Run()
    {
        string myTask = null;

        //time to work until i die
        while (true)
        {
            //discard the old task, if any
            myTask = string.Empty;

            //check if we have anything to do
            if (this._tasksTray.Count == 0)
            {
                lock (this._tasksTray)
                {
                    //no jobs; time to chill.
                    Console.WriteLine("Employee# {0} is taking a break.", this._employeeID);
                    Monitor.Wait(this._tasksTray);
                }
            }

            //work finally came in. Grab the tray and get a task.
            lock (this._tasksTray)
            {
                if (this._tasksTray.Count > 0)
                {
                    //yes, i got a job. Remove the task from the tray, so no one else can get it.
                    myTask = this._tasksTray.Dequeue();
                }
            }

            //time to process the task
            if (!string.IsNullOrEmpty(myTask))
            {
                Console.WriteLine("Employee# {0} has completed job: {1}.", this._employeeID, myTask);
                Thread.Sleep(1000);
            }
        }
    }
}

/// <summary>
/// Represent your standard manager that manages a tray of jobs.
///  
/// for ex)
/// 1) he has a certain number of employees.
/// 2) he interacts with clients and get jobs
/// 3) he post jobs to JIRA and notifies his employees to start working.
/// </summary>
public class Manager
{
    private Queue<string> _taskTray;
    private List<Employee> _employees;

    public Manager(int numOfEmployees = 5)
    {
        //Tray of jobs. This is a shared resource between the manager and employees, so we have to make sure only one person access it at any time.
        this._taskTray = new Queue<string>();

        //set employees
        this._employees = new List<Employee>();
        for (var i = 0; i < numOfEmployees; i++)
        {
            this._employees.Add(new Employee(i.ToString(), this._taskTray));
        }
    }

    public void AddTask(params string[] newTasks)
    {
        lock (this._taskTray)
        {
            //add new tasks to the tray
            foreach (var task in newTasks)
            {
                this._taskTray.Enqueue(task);
            }


            //break time over. time to get back to work.
            Console.WriteLine("
Manager said: Wake up. Time to work. We got {0} jobs.
", newTasks.Length);
            Monitor.PulseAll(this._taskTray);
        }
    }

}


//Main
class Program
{

    static void Main(string[] args)
    {
        try
        {
            //create a manager
            var manager = new Manager(3);

            //add jobs
            manager.AddTask("Task 1", "task 2");

            //simulate downtime
            Thread.Sleep(5000);

            //add more jobs
            var jobs = new List<string>();
            for (int i = 0; i < 10; i++)
            {
                jobs.Add("Project# " + i.ToString());
            }
            manager.AddTask(jobs.ToArray());

        }
        catch (Exception ex)
        {

            Console.WriteLine(ex.Message);
        }

        Console.WriteLine("press any key to end the program.");
        Console.Read();
    }


}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...