简体   繁体   English

如何创建和使用后台线程从另一个线程更改对象

[英]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.我想这是许多项目的普通任务,我只是不知道该怎么做。

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. .Net 有一个丰富的线程库,所以我把它留给你。

for ex) 1) use a delegate and call BeginInvoke 2) system.threading.Thread namespace 3) System.Threading.Tasks namespace例如) 1) 使用委托并调用 BeginInvoke 2) system.threading.Thread 命名空间 3) System.Threading.Tasks 命名空间

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("\nManager said: Wake up. Time to work. We got {0} jobs.\n", 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();
    }


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM