我对 .net 4.5 中的线程模型(或一般的线程)仍然相当陌生。我正在尝试构建一组抽象类,以实现用于多线程处理一系列类似任务的框架。规则是输入的第一行告诉集合中有多少问题,接下来的行包含每个问题的输入。一组输入的多少行可能因一项任务而异,但对于给定类型的问题通常是一致的。每个问题都是以单行文本作为其输出。
目标是能够从这些类继承,并且只需要担心实现 CreateWorker 和 DoWork 方法。UI 将调用 ProcessInput 来开始工作,并调用 WriteOutput 来列出结果。
到目前为止,我拥有的基本模板是:
public abstract class Wrapper
{
protected int N;
protected WorkerBase[] ProblemSet;
protected List<Task> Tasks;
public virtual void ProcessInput(TextReader input)
{
string Line = input.ReadLine();
N = int.Parse(Line);
ProblemSet = new WorkerBase[N];
Tasks= new List<Task>(N);
for (int index = 0; index < N; index++)
{
WorkerBase T = CreateWorker(input);
Tasks.Add(T.DoWorkAsync());
ProblemSet[index] = T;
}
}
public virtual bool WriteOutput(TextWriter outputStream, int timeout)
{
bool Complete = Task.WaitAll(Tasks.ToArray(), timeout);
for (int index = 0; index < N; index++)
{
outputStream.WriteLine(ProblemSet[index].Result);
}
return Complete;
}
protected abstract WorkerBase CreateWorker(TextReader inputStream);
protected abstract class WorkerBase
{
public string Result
{
get;
protected set;
}
protected abstract void DoWork();
public Task DoWorkAsync()
{
return Task.Run(() => DoWork());
}
}
}
照原样,这符合我的要求。但现在我想向 Wrapper 类添加中止功能,它能够停止所有线程。所以问题是,我如何在这个结构中使用中止功能,以便我的 UI 可以在单击取消按钮时中止进程?最好不必在 DoWork 实现中编写额外的代码。
我发现了传递取消令牌以中止任务的模式,但是我发现的每个版本都需要 DoWork 检查令牌的状态并自行中止。我真的想要一种从方法外部中止 DoWork 的方法。