如何创建和使用后台线程从另一个线程更改对象 [英] How to create and use background thread to change object from another thread

查看:90
本文介绍了如何创建和使用后台线程从另一个线程更改对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在主线程中有对象.我需要创建后台线程,该线程将永久解析网站,并在每次后台线程获取新数据时从主线程更改对象. 这样做的正确方法是什么? 另一个问题:如何创建将永久运行的后台线程?

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?

我需要类似的东西

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.

推荐答案

后台线程的作用域是主线程.因此,只要控制台应用程序仍在运行,它将一直运行. .Net具有丰富的线程库,因此我将其留给您.

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.

例如) 1)使用委托并调用BeginInvoke 2)system.threading.Thread命名空间 3)System.Threading.Tasks命名空间

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("\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();
    }


}

这篇关于如何创建和使用后台线程从另一个线程更改对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆