C# 如何使用Task.run执行后台工作程序的Do_Work()功能
我在路径列表中存储的特定路径中并行移动4个对象,当每个对象完成一个路径(特定坐标)时,它将切换到另一个 我使用了4个后台工作人员在后台执行这样的工作,在每次调用中,每个后台工作人员都应该尝试从文本文件中提取6条路径(染色体),每个路径存储在不同的6个列表中,每个列表包含每个路径的坐标。然后将坐标转换为2D点以执行投影,并在特定深度处执行每条路径,因为使用投影技术在不同层上移动这些对象的路径,即每个对象(工作者)将在不同层上移动 每个工作人员应使用一条路径(染色体)前后移动对象,然后切换到下一条路径,并在切换到下一条路径之前完成第一次尝试(路径),以计算所消耗的时间和其他因素,如“适应度”函数 以下是Do_Work()方法之一的示例: 我在循环250次的循环中声明了它们,每次都通过调用另一个包含以下行的方法在此循环中调用它们:C# 如何使用Task.run执行后台工作程序的Do_Work()功能,c#,multithreading,task-parallel-library,backgroundworker,C#,Multithreading,Task Parallel Library,Backgroundworker,我在路径列表中存储的特定路径中并行移动4个对象,当每个对象完成一个路径(特定坐标)时,它将切换到另一个 我使用了4个后台工作人员在后台执行这样的工作,在每次调用中,每个后台工作人员都应该尝试从文本文件中提取6条路径(染色体),每个路径存储在不同的6个列表中,每个列表包含每个路径的坐标。然后将坐标转换为2D点以执行投影,并在特定深度处执行每条路径,因为使用投影技术在不同层上移动这些对象的路径,即每个对象(工作者)将在不同层上移动 每个工作人员应使用一条路径(染色体)前后移动对象,然后切换到下一条路
auv0Genetic.RunWorkerAsync(geneticIteration); // start AUV # 1
问题:
循环和Do_Work()
方法之间没有同步,即循环在4个后台工作人员完成工作之前开始新的迭代,其中每个迭代都有一个包含6个不同路径(染色体)的列表每个后台工作人员都应该在下一次使用新列表的迭代之前尝试它们。在进入下一个迭代之前,我需要完全停止工作人员。我在循环外放了一个消息框,在循环完成后,即使所有工人都停止了,我也没有看到它出现
我的问题是:
我在使用后台工作人员时遇到了一些问题,所以我想知道是否可以使用Task类,如果可以的话。。那么如何使用任务。运行在Do_Work()
方法中执行相同的工作?我的假设能够给出答案:
- 这将使用带有关联任务的对象,因为您似乎对使用任务感兴趣,是的,它将比JerrySrigging后台工作人员更加流畅
- 我将假设您理解您的业务逻辑和
我没有必要这么做
- 我将重点介绍一种使用选项以统一方式处理数据的方法
增加容量
- 当然,我愿意修正和阐明不清楚的地方
- 这应该被视为Psuedo代码,我并没有编译这段代码,由于缺少一些想法,它也不会编译。可能需要一些编辑来修复一些小问题,因为我在这里是为了大局而不是细节
代码
包括
包括您将需要的:
using System;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Diagnostics;
处理循环
这是您可以从单个后台工作程序调用的主循环:
public void BeginProcess()
{
//This is the limitation on threads/cpu usage
var maxWorkers = 4;
//You could tackle how to go through the loop many ways this was how I was doing it for a simple file transfer program so I didn't change the paradigm
var currentWorker = 0;
//This is the Worker List that will hold and then run our chromosome business logic
var ChromosomeWorkers = new List<ChromWorker>();
//I am not sure based on the code how you are running through this, but here is a population example
foreach (var chromTemplate in ChromosomeTemplates)
{
var cw = new ChromWorker(/*pass in appropriate arrays etc*/);
ChromosomeWorkers.Add(cw);
//If the count of Running workers is less than Max Workers and we are not at the end of the list Continue starting them
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
ChromosomeWorkers[currentWorker].Start();
currentWorker++;
}
}
//Transition from Creation to Pure Processing
do
{
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
FilesToBeTransferred[currentWorker].Start();
currentWorker++;
}
else
{
//If the workers are maxed then sleep for a bit on this thread
Thread.Sleep(150);
}
}
while (currentWorker < ChromosomeWorkers.Count);
}
public void BeginProcess()
{
//这是对线程/cpu使用的限制
var-maxWorkers=4;
//你可以用很多方法来解决如何通过循环,这就是我为一个简单的文件传输程序所做的,所以我没有改变范例
var-currentWorker=0;
//这是将保存并运行业务逻辑的工作人员列表
var ChromosomeWorkers=新列表();
//根据代码,我不确定您是如何执行此操作的,但这里有一个总体示例
foreach(染色体模板中的var chromTemplate)
{
var cw=新的ChromWorker(/*通过适当的数组等*/);
染色体工作者。添加(cw);
//如果正在运行的工时数小于最大工时数,并且我们不在列表的末尾,请继续启动它们
if(ChromosomeWorkers.Count(x=>x.Running)x.Running)
工人阶级
注意:您可能需要解释许多其他任务状态,如IsFaulted等。我希望保持这一点的简洁性,因此我没有讨论这些情况,但您可能需要解释它们
这是工人阶级,将完成大部分步法:
public class ChromWorker
{
private Task _t;
bool isConsumed = false;
pathChromosom1 [,];
string _Key = string.Empty;
List<Tag> _Tags = new List<Tag>();
public ChromWorker(/*Data that might be useful in your worker*/)
{
pathChromosom1 = inChromosomeArrays;
}
public bool Running
{
get
{
if (_t == null || _t.IsCompleted ) return false;
return true;
}
}
public bool Done
{
get
{
return _t != null && _t.IsCompleted;
}
}
public bool Ready
{
get { return _t == null; }
}
public void Start()
{
_t = new Task(_Run);
_t.Start();
}
private void _Run()
{
double tries = 0;
bool Handled = false;
while (!Handled && tries < Math.Pow(10, 6))
{
//Increase our giveup loop
tries++;
try
{
/* your Business logic */
Handled = true;
}
catch (Exception e)
{
Console.WriteLine("Exception: {0} StackTrace: {1}", e.Message, e.StackTrace);
}
}
}
}
公共类
{
私人任务;;
bool isConsumed=false;
路径染色体1[,];
string _Key=string.Empty;
列表_标记=新列表();
公共工作者(/*在工作者中可能有用的数据*/)
{
pathChromosom1=inChromosomearray;
}
公营学校
{
得到
{
如果(_t==null | | u t.IsCompleted)返回false;
返回true;
}
}
公共广播结束了
{
得到
{
return\u t!=null&&u t.IsCompleted;
}
}
公共厕所准备好了吗
{
获取{return\u t==null;}
}
公开作废开始()
{
_t=新任务(_Run);
_t、 Start();
}
私有void_Run()
{
双重尝试=0;
bool=false;
而(!Handled&&tryspublic void BeginProcess()
{
//This is the limitation on threads/cpu usage
var maxWorkers = 4;
//You could tackle how to go through the loop many ways this was how I was doing it for a simple file transfer program so I didn't change the paradigm
var currentWorker = 0;
//This is the Worker List that will hold and then run our chromosome business logic
var ChromosomeWorkers = new List<ChromWorker>();
//I am not sure based on the code how you are running through this, but here is a population example
foreach (var chromTemplate in ChromosomeTemplates)
{
var cw = new ChromWorker(/*pass in appropriate arrays etc*/);
ChromosomeWorkers.Add(cw);
//If the count of Running workers is less than Max Workers and we are not at the end of the list Continue starting them
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
ChromosomeWorkers[currentWorker].Start();
currentWorker++;
}
}
//Transition from Creation to Pure Processing
do
{
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
FilesToBeTransferred[currentWorker].Start();
currentWorker++;
}
else
{
//If the workers are maxed then sleep for a bit on this thread
Thread.Sleep(150);
}
}
while (currentWorker < ChromosomeWorkers.Count);
}
public class ChromWorker
{
private Task _t;
bool isConsumed = false;
pathChromosom1 [,];
string _Key = string.Empty;
List<Tag> _Tags = new List<Tag>();
public ChromWorker(/*Data that might be useful in your worker*/)
{
pathChromosom1 = inChromosomeArrays;
}
public bool Running
{
get
{
if (_t == null || _t.IsCompleted ) return false;
return true;
}
}
public bool Done
{
get
{
return _t != null && _t.IsCompleted;
}
}
public bool Ready
{
get { return _t == null; }
}
public void Start()
{
_t = new Task(_Run);
_t.Start();
}
private void _Run()
{
double tries = 0;
bool Handled = false;
while (!Handled && tries < Math.Pow(10, 6))
{
//Increase our giveup loop
tries++;
try
{
/* your Business logic */
Handled = true;
}
catch (Exception e)
{
Console.WriteLine("Exception: {0} StackTrace: {1}", e.Message, e.StackTrace);
}
}
}
}
public async Task WorkerStartedMethod()
{
for(int i = 0; i<=250; i++)
{
List<Task> tasks = new List<Task>();
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
await Task.WhenAll(tasks);
}
}