一旦你离开最初启动任务的方法,有没有办法按ID获取当前正在运行的任务?我想以某种方式得到当前的任务,这样我就可以在执行中停止其中一些而不会中断程序的流程。
例如:
class Test
{
List<Task> listOfTasks = new List<Task>();
void taskCaller()
{
try
{
var myTask = Task.Factory.StartNew(()=> testMethod());
listOfTasks.Add(myTask);
}
catch (System.Exception)
{
//...
throw;
}
}
void taskGetter()
{
foreach (var item in listOfTasks)
{
if(item == something)
{
item.KillExecution();
}
}
}
private void testMethod()
{
// doing something
throw new NotImplementedException();
}
}
修改
我希望它在没有取消令牌的情况下完成,如果可能的话,因为它对我不起作用,因为我想要它,因为我正在运行一个定时器从DB获取DLL并且取消令牌只有在我立即使用{{1但是,如果我尝试token.Cancel()
它不起作用,因为它只在任务完成执行后才被触发,这种想法不是。
EDIT2:
不要复制大量的代码,这是整个流程的伪:
token.CancelAfter()
继续plast1k建议......
当我检查字典时,如果在这种情况下请求取消,它会显示new timer(repeat method every xx time units)
open DB
do some work
save DB
,但它对正在运行的任务没有任何作用
true
答案 0 :(得分:2)
正如您可能已经研究过的那样,到目前为止,取消任务的唯一方法是使用canceltoken使其知道取消并使其具有取消感知功能。此外,这也是首选方法。但是,由于您的问题提到您不能使用取消源,您可以使用另一个SO答案(包括链接)中提到的技术。
链接中的要点,您可以创建这些任务并在不同的线程上运行它们,并在您想要取消任务时中止该线程
答案 1 :(得分:1)
确保您实际处理任务中的取消(通过 cancelToken.ThrowIfCancellationRequested()),因为在令牌源上调用取消仅取消任务计划,它实际上不会停止执行。
停止任务的正确方法是使用取消令牌。 查看此处的示例
https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx
在这里
答案 2 :(得分:1)
虽然您应该看到usaipavan的答案和链接以获得正确的取消技术,但为了跟踪您的线程或任务,您只需将它们添加到词典而不是列表并分配您选择的ID。它可以是整数或字符串或任何东西,在本例中它是GUID。
Dictionary<Guid, Task> listofTasks = new Dictionary<Guid, Task>();
public Guid StartTask()
{
Task myTask = Task.Factory.StartNew(()=> testMethod());
Guid taskID = Guid.NewGuid();
listOfTasks.Add(taskID, myTask);
return taskID;
}
public void CancelTask(Guid id)
{
// listOfTasks[id].choose_your_own_task_cancellation_adventure()
}
如果你可以使用取消令牌,你可以将它们存储在字典/另一个字典中/作为元组。如果你想识别这些任务的组(即,取消&#34; DB Query&#34;操作的所有要求),你可以做这样的事情
public class TaskWrapper
{
public TaskWrapper(string operationID, Task task, CancellationTokenSource cancellationSource)
{
this.OperationID = operationID;
this.Task = task;
this.CancellationSource = cancellationSource;
}
public string OperationID { get; set; }
public Task Task { get; set; }
public CancellationTokenSource CancellationSource { get; set; }
}
private Dictionary<Guid, TaskWrapper> ListOfTasks = new Dictionary<Guid, TaskWrapper>();
// populate the list
public void CancelAll(string operation)
{
listOfTasks.Where(a => a.OperationID == operation).CancellationSource.Cancel();
}