Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#取消正在执行长时间运行的sql查询的任务列表_C#_Asp.net_Parallel Processing_Task Parallel Library_Cancellation Token - Fatal编程技术网

C#取消正在执行长时间运行的sql查询的任务列表

C#取消正在执行长时间运行的sql查询的任务列表,c#,asp.net,parallel-processing,task-parallel-library,cancellation-token,C#,Asp.net,Parallel Processing,Task Parallel Library,Cancellation Token,我需要取消等待时间到期后运行SQL查询的任务列表。我可以实现CancellationToken来取消任务。但是取消是合作的,因此这意味着我必须在每一步之前检查操作中的取消令牌状态。但在我的例子中,sql查询需要很长时间,我只能在执行查询之前或之后检查cancel令牌状态。在后一种情况下,它是无用的,那么如何根据cancel令牌状态取消这些任务中的查询执行呢 public void EnqueueTask(Action action, CancellationToken cancelToken =

我需要取消等待时间到期后运行SQL查询的任务列表。我可以实现CancellationToken来取消任务。但是取消是合作的,因此这意味着我必须在每一步之前检查操作中的取消令牌状态。但在我的例子中,sql查询需要很长时间,我只能在执行查询之前或之后检查cancel令牌状态。在后一种情况下,它是无用的,那么如何根据cancel令牌状态取消这些任务中的查询执行呢

public void EnqueueTask(Action action, CancellationToken cancelToken = default(CancellationToken))
{
    var task = new Task(action, cancelToken, TaskCreationOptions.LongRunning);
    if (_workTaskQueue.TryAdd(task))
    {
        TaskHandler?.Invoke
            (new TaskProcessingArguments
            {
                ISTaskAdded = true,
                Message = "Task Added to Queue",
                PendingTaskCount = _workTaskQueue.Count,
            });
    }
    else
    {
        TaskHandler?.Invoke
            (new TaskProcessingArguments
            {
                ISTaskAdded = false,
                Message = "Timedout while adding Task to Queue",
                PendingTaskCount = _workTaskQueue.Count,
            });
    }
}

public void DequeueTask(int maxConcurrency, CancellationToken ct)
{
    var tasks = new List<Task>();
    using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency))
    {
        foreach (var task in _workTaskQueue.GetConsumingEnumerable())
        {
            try
            {
                if (!(task.IsCanceled) && task.Status == TaskStatus.Created)
                {
                    tasks.Add(task);
                    task.Start();
                }
            }
            finally {
                concurrencySemaphore.Release();
            }
        }
    }
    Task.WaitAll(tasks.ToArray());
}

    void StartWorker()
    {
        Task.Factory.StartNew(() =>
        {
            try
            {
                taskQueue.DequeueTask(maxConcurrency, cancellationToken);
            }
            finally {
                lock (syncObj)
                {
                    IsCompleted = true;
                }
                //Logger.Info("Closing Worker task!!!");
            }
        }, TaskCreationOptions.LongRunning);
    }
public void排队任务(操作操作,CancellationToken cancelToken=default(CancellationToken))
{
var任务=新任务(操作、取消令牌、TaskCreationOptions.LongRunning);
if(_workTaskQueue.TryAdd(任务))
{
TaskHandler?调用
(新任务处理争论)
{
ISTaskAdded=true,
Message=“任务已添加到队列”,
PendingTaskCount=\u workTaskQueue.Count,
});
}
其他的
{
TaskHandler?调用
(新任务处理争论)
{
ISTaskAdded=false,
Message=“将任务添加到队列时超时”,
PendingTaskCount=\u workTaskQueue.Count,
});
}
}
public void出列任务(int-maxConcurrency,CancellationToken-ct)
{
var tasks=新列表();
使用(SemaphoreSlim concurrency semaphore=new SemaphoreSlim(maxConcurrency))
{
foreach(在_workTaskQueue.GetConsumingEnumerable()中的var task)
{
尝试
{
如果(!(task.IsCanceled)&&task.Status==TaskStatus.Created)
{
任务。添加(任务);
task.Start();
}
}
最后{
并发Maphore.Release();
}
}
}
Task.WaitAll(tasks.ToArray());
}
void StartWorker()
{
Task.Factory.StartNew(()=>
{
尝试
{
taskQueue.DequeueTask(maxConcurrency,cancellationToken);
}
最后{
锁(同步对象)
{
IsCompleted=真;
}
//Logger.Info(“关闭工作任务!!!”;
}
},TaskCreationOptions.LongRunning);
}

编写一个使用新线程启动查询的任务,该任务可以继续检查CancelationToken的状态,并在需要时终止该线程


例如,您可以扩展任务并添加此功能。

您需要在作为操作实例传递到排队任务方法的函数中使用取消令牌

例如,以下代码显示了如何使用CancellationToken终止SQL命令的执行:

    using (SqlConnection conn = new SqlConnection(sqlConnection))
    {
        conn.Open();
        var cmd = conn.CreateCommand();

        using (cancellationToken.Register(() => cmd.Cancel()))
        {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
        }
    }

这取决于您的代码,您使用什么来执行查询?有时可以将cancellationToken作为参数传递给异步方法。请记住:在特定时间后取消SQL查询最好是将超时(毫秒)传递到执行查询的位置(而不是cancellationtoken)。如果您不知道何时停止(例如,用户想要停止),您只会使用cancellationtoken。Maerlin,我添加了一些示例代码。我已经为sql查询设置了单独的超时时间,但我正在使用信号量以小批量运行任务,因此假设批次中的每个查询在10秒后超时,并且有10个类似的批次,这相当于100秒的运行时间,相反,我想在10秒后取消所有任务的执行。阅读优秀的博客,其中有很多关于异步操作的文章。你想在取消令牌周围放置一个using块。注册,在
ExecuteNonQuery
之后立即关闭感谢@Tim,修正了。u Show cancellationToken,但是你没有显示它属于哪个类或函数,这也解决了我的问题,但是我使用Olexiy的答案,因为它看起来更简单。非常感谢。无法给你+1,因为我没有足够的重复次数:|