如何创建和使用后台线程从另一个线程更改对象 [英] 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?
我需要类似的东西
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屋!