C#获取异步任务

时间:2016-10-27 15:09:04

标签: c# asynchronous task

一旦你离开最初启动任务的方法,有没有办法按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

3 个答案:

答案 0 :(得分:2)

正如您可能已经研究过的那样,到目前为止,取消任务的唯一方法是使用canceltoken使其知道取消并使其具有取消感知功能。此外,这也是首选方法。但是,由于您的问题提到您不能使用取消源,您可以使用另一个SO答案(包括链接)中提到的技术。

链接中的要点,您可以创建这些任务并在不同的线程上运行它们,并在您想要取消任务时中止该线程

How do I force a Task to stop?

答案 1 :(得分:1)

确保您实际处理任务中的取消(通过 cancelToken.ThrowIfCancellationRequested()),因为在令牌源上调用取消仅取消任务计划,它实际上不会停止执行。

停止任务的正确方法是使用取消令牌。 查看此处的示例

https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

在这里

https://blogs.msdn.microsoft.com/andrewarnottms/2014/03/19/recommended-patterns-for-cancellationtoken/

答案 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();
}