Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.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# 跟踪并取消以前的任务';执行新排队任务时的s CancellationTokens_C#_Asp.net_Asp.net Web Api_Parallel Processing_Task Parallel Library - Fatal编程技术网

C# 跟踪并取消以前的任务';执行新排队任务时的s CancellationTokens

C# 跟踪并取消以前的任务';执行新排队任务时的s CancellationTokens,c#,asp.net,asp.net-web-api,parallel-processing,task-parallel-library,C#,Asp.net,Asp.net Web Api,Parallel Processing,Task Parallel Library,我请求对以下内容进行代码审查,这超出了我的正常范围,我想知道算法是否正确?其目的是跟踪添加到后台工作队列的任务的取消令牌。它应该首先对所有现有令牌调用cancel,将自己的令牌添加到ConcurrentBag,然后执行工作。谢谢 编辑:基本上我是在问,这是正确的吗?在此方法中执行的较新任务(在while中)是否会取消在//网络请求时暂停的较旧任务,从而防止不必要的工作//将作为集合的缓存项重新水化只需由最新执行的任务(不是每个执行的任务)运行一次 公共类管理器{ 私有静态只读Concurrent

我请求对以下内容进行代码审查,这超出了我的正常范围,我想知道算法是否正确?其目的是跟踪添加到后台工作队列的任务的取消令牌。它应该首先对所有现有令牌调用cancel,将自己的令牌添加到ConcurrentBag,然后执行工作。谢谢

编辑:基本上我是在问,这是正确的吗?在此方法中执行的较新任务(在
while
中)是否会取消在
//网络请求时暂停的较旧任务,从而防止不必要的工作
//将作为集合的缓存项重新水化
只需由最新执行的任务(不是每个执行的任务)运行一次

公共类管理器{
私有静态只读ConcurrentBag CancelTokens=新ConcurrentBag();
//下面的方法被这样调用
//HostingEnvironment.QueueBackgroundWorkItem(异步(cancelationToken)=>Wait PerformTask和CancelPreviousTasks(cancelationToken));
公共异步任务PerformTask和CancelPreviousTasks(CancellationToken ct)
{
尝试
{
//取消以前的所有任务
而(!CancelTokens.IsEmpty)
{
CancellationToken previousTaskCancelToken;
CancelTokens.TryTake(out previousTaskCancelToken);
如果(先前的TaskCancelToken.canbecancelled)
{
CancellationTokenSource.CreateLinkedTokenSource(previousTaskCancelToken).Cancel();
}
}
CancelTokens.Add(ct);//将此任务的CancellationToken添加到ConcurrentBag
//将单个缓存项重新水化
//为了提高性能,只有最新的任务需要运行此命令
如果(!ct.iscancellationrequest)
{
//将作为集合的缓存项重新水化
}
}
捕获(例外e)
{
TelemetryManager.TrackException(“PerformTask和CancelPreviousTasks中的错误”,e);
}
}
}

在修改了
PerformTask和CancelPreviousTasks
方法以采用
CancellationTokenSource
而不是
CancellationToken
之后,我觉得它似乎起到了作用。堆积起来的电话确实会被取消

    public class Program
{
    static void Main(string[] args)
    {

        ///////////////////////////////////////////////////////////////////////////////
        // Test
        //
        // Out:
        //  Thread [852] performed the work
        //  Was last executing thread: FALSE. Was #897
        //  QueueUserWorkItem Call 1762
        //  Thread [854] performed the work
        //  Was last executing thread: FALSE. Was #1412
        //  QueueUserWorkItem Call 1391
        //  Thread [1836] performed the work
        //  Was last executing thread: TRUE. Was #2000
        //  QueueUserWorkItem Call 1984
        //
        ///////////////////////////////////////////////////////////////////////////////


        Manager mgr = new Manager();

        // 2000 rapid updates 
        for (int i = 0; i < 2000; i++)
        {
            new Thread(new ParameterizedThreadStart((id) => {
                // Thread.Sleep(2000 - (int) id);
                Random rand = new Random();
                Thread.Sleep(rand.Next(2, 500));
                CancellationTokenSource ctSource = new CancellationTokenSource();
                ThreadPool.QueueUserWorkItem(async (state) => await mgr.PerformTaskAndCancelPreviousTasks(ctSource, (int) id, rand.Next(7, 2500)));
            })).Start(i);
        };
        Task.Delay(15000).Wait(); // Keep ThreadPool alive
    }
}

public class Manager
{

    private static readonly ConcurrentBag<CancellationTokenSource> CancelTokens = new ConcurrentBag<CancellationTokenSource>();
    private static volatile int AtomicCounter = 0;

    // Below method gets called like this
    // HostingEnvironment.QueueBackgroundWorkItem(async (cancelationToken) => await PerformTaskAndCancelPreviousTasks(cancelationToken));

    public async Task PerformTaskAndCancelPreviousTasks(CancellationTokenSource cts, int tN, int delay)
    {
        try
        {
            Interlocked.Increment(ref AtomicCounter);
            // Cancel all previous tasks
            while (!CancelTokens.IsEmpty)
            {
                CancellationTokenSource previousTaskCancelTokenSource = null;
                CancelTokens.TryTake(out previousTaskCancelTokenSource);
                if (previousTaskCancelTokenSource != null)
                {
                    previousTaskCancelTokenSource.Cancel();
                }
            }
            CancelTokens.Add(cts); // Add this task's CancellationToken to ConcurrentBag

            await Task.Delay(delay); // Simulate network request

            // Only the newest task needs to run this, for performance
            if (!cts.Token.IsCancellationRequested)
            {
                // Rehydrate a cache item that is a collection
                Console.WriteLine(string.Format("Thread [{0}] performed the work", Thread.CurrentThread.ManagedThreadId));
                Console.WriteLine(string.Format("Was last executing thread: {0}. Was #{1}", AtomicCounter == 2000 ? "TRUE" : "FALSE", AtomicCounter));
                Console.WriteLine(string.Format("QueueUserWorkItem Call {0}", tN));
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception occurred in:\r\n" + e.StackTrace);
        }
    }
}
公共类程序
{
静态void Main(字符串[]参数)
{
///////////////////////////////////////////////////////////////////////////////
//试验
//
//输出:
//线程[852]执行了该工作
//Was最后一个执行线程:FALSE。Was#897
//QueueUserWorkItem调用1762
//线程[854]执行了该工作
//Was最后一个执行线程:FALSE。Was#1412
//QueueUserWorkItem调用1391
//线程[1836]执行了该工作
//Was最后一个执行线程:TRUE.Was#2000
//QueueUserWorkItem调用1984
//
///////////////////////////////////////////////////////////////////////////////
经理=新经理();
//2000快速更新
对于(int i=0;i<2000;i++)
{
新线程(新的参数化线程开始((id)=>{
//线程睡眠(2000-(int)id);
Random rand=新的Random();
Thread.Sleep(兰特下一步(2500));
CancellationTokenSource ctSource=新的CancellationTokenSource();
ThreadPool.QueueUserWorkItem(异步(状态)=>Wait-mgr.PerformTask和CancelPreviousTasks(ctSource,(int)id,rand.Next(72500));
}))·启动(i);
};
Task.Delay(15000.Wait();//保持线程池活动
}
}
公共班级经理
{
私有静态只读ConcurrentBag CancelTokens=新ConcurrentBag();
私有静态volatile int原子计数器=0;
//下面的方法被这样调用
//HostingEnvironment.QueueBackgroundWorkItem(异步(cancelationToken)=>Wait PerformTask和CancelPreviousTasks(cancelationToken));
公共异步任务PerformTask和CancelPreviousTasks(CancellationTokenSource cts、int tN、int delay)
{
尝试
{
联锁增量(参考原子计数器);
//取消以前的所有任务
而(!CancelTokens.IsEmpty)
{
CancellationTokenSource previousTaskCancelTokenSource=null;
CancelTokens.TryTake(out previousTaskCancelTokenSource);
if(previousTaskCancelTokenSource!=null)
{
previousTaskCancelTokenSource.Cancel();
}
}
CancelTokens.Add(cts);//将此任务的CancellationToken添加到ConcurrentBag
等待任务。延迟(延迟);//模拟网络请求
//为了提高性能,只有最新的任务需要运行此命令
如果(!cts.Token.IsCancellationRequested)
{
//将作为集合的缓存项重新水化
WriteLine(string.Format(“线程[{0}]执行了工作”,Thread.CurrentThread.ManagedThreadId));
WriteLine(string.Format(“Was最后一个执行线程:{0}.Was{1}”,AtomicCounter==2000?“TRUE”:“FALSE”,AtomicCounter));
WriteLine(string.Format(“QueueUserWorkItem调用{0}”,tN));
}
}
捕获(例外e)
{
Console.WriteLine(“在:\r\n“+e.StackTrace中发生异常”);
}
}
}
    public class Program
{
    static void Main(string[] args)
    {

        ///////////////////////////////////////////////////////////////////////////////
        // Test
        //
        // Out:
        //  Thread [852] performed the work
        //  Was last executing thread: FALSE. Was #897
        //  QueueUserWorkItem Call 1762
        //  Thread [854] performed the work
        //  Was last executing thread: FALSE. Was #1412
        //  QueueUserWorkItem Call 1391
        //  Thread [1836] performed the work
        //  Was last executing thread: TRUE. Was #2000
        //  QueueUserWorkItem Call 1984
        //
        ///////////////////////////////////////////////////////////////////////////////


        Manager mgr = new Manager();

        // 2000 rapid updates 
        for (int i = 0; i < 2000; i++)
        {
            new Thread(new ParameterizedThreadStart((id) => {
                // Thread.Sleep(2000 - (int) id);
                Random rand = new Random();
                Thread.Sleep(rand.Next(2, 500));
                CancellationTokenSource ctSource = new CancellationTokenSource();
                ThreadPool.QueueUserWorkItem(async (state) => await mgr.PerformTaskAndCancelPreviousTasks(ctSource, (int) id, rand.Next(7, 2500)));
            })).Start(i);
        };
        Task.Delay(15000).Wait(); // Keep ThreadPool alive
    }
}

public class Manager
{

    private static readonly ConcurrentBag<CancellationTokenSource> CancelTokens = new ConcurrentBag<CancellationTokenSource>();
    private static volatile int AtomicCounter = 0;

    // Below method gets called like this
    // HostingEnvironment.QueueBackgroundWorkItem(async (cancelationToken) => await PerformTaskAndCancelPreviousTasks(cancelationToken));

    public async Task PerformTaskAndCancelPreviousTasks(CancellationTokenSource cts, int tN, int delay)
    {
        try
        {
            Interlocked.Increment(ref AtomicCounter);
            // Cancel all previous tasks
            while (!CancelTokens.IsEmpty)
            {
                CancellationTokenSource previousTaskCancelTokenSource = null;
                CancelTokens.TryTake(out previousTaskCancelTokenSource);
                if (previousTaskCancelTokenSource != null)
                {
                    previousTaskCancelTokenSource.Cancel();
                }
            }
            CancelTokens.Add(cts); // Add this task's CancellationToken to ConcurrentBag

            await Task.Delay(delay); // Simulate network request

            // Only the newest task needs to run this, for performance
            if (!cts.Token.IsCancellationRequested)
            {
                // Rehydrate a cache item that is a collection
                Console.WriteLine(string.Format("Thread [{0}] performed the work", Thread.CurrentThread.ManagedThreadId));
                Console.WriteLine(string.Format("Was last executing thread: {0}. Was #{1}", AtomicCounter == 2000 ? "TRUE" : "FALSE", AtomicCounter));
                Console.WriteLine(string.Format("QueueUserWorkItem Call {0}", tN));
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception occurred in:\r\n" + e.StackTrace);
        }
    }
}