Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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/9/csharp-4.0/2.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# 从事件的无限并行Foreach循环取消令牌_C#_C# 4.0_C# 3.0 - Fatal编程技术网

C# 从事件的无限并行Foreach循环取消令牌

C# 从事件的无限并行Foreach循环取消令牌,c#,c#-4.0,c#-3.0,C#,C# 4.0,C# 3.0,我已经编写了一些代码,其中我使用Parallel.Foreach为少数项目与无限循环并行工作,即每60秒工作一次 但是在这里,我的消息可以由用户随时更改,我需要用新消息重新处理。 为此,我需要取消无限并行.Foreach循环以重新处理更新的消息 当我试图重新处理main方法时,它对于新消息来说工作正常,但是它运行了两次,因为以前计划的任务没有取消。我假设我需要取消parralel.Foreach循环中的进程,然后重新运行,以获得具有新计划的更新消息 所以,有谁能帮我取消已安排在下一个60秒的排队

我已经编写了一些代码,其中我使用Parallel.Foreach为少数项目与无限循环并行工作,即每60秒工作一次

但是在这里,我的消息可以由用户随时更改,我需要用新消息重新处理。 为此,我需要取消无限并行.Foreach循环以重新处理更新的消息

当我试图重新处理main方法时,它对于新消息来说工作正常,但是它运行了两次,因为以前计划的任务没有取消。我假设我需要取消parralel.Foreach循环中的进程,然后重新运行,以获得具有新计划的更新消息

所以,有谁能帮我取消已安排在下一个60秒的排队任务吗

static void Main(string[] args)
    {
        List<RealTimeMessage> messages = GetRealTimeMessage();
        Parallel.ForEach(messages, (message) =>
        {
            processMessage(message);
        });

        Console.ReadLine();
    }

private static async void processMessage(RealTimeMessage message)
{
    try
    {
        while (true)
        {
            await Task.Delay(TimeSpan.FromSeconds(60));
            await Task.Run(() => ProceesRequest(message));
        }
    }
    catch (Exception)
    {
        Console.WriteLine("Critical error");
    }
}

private static List<RealTimeMessage> GetRealTimeMessage()
{
    List<RealTimeMessage> realTimeMessages = new List<RealTimeMessage>();
    realTimeMessages.Add(new RealTimeMessage { MessageText = "Message 4", IntervalTime = "1", MessageType = "AIDX", TimeOfDay = "" });
    realTimeMessages.Add(new RealTimeMessage { MessageText = "Message 5", IntervalTime = "2", MessageType = "AMSX", TimeOfDay = "" });

    return realTimeMessages;
}
private static void ProceesRequest(RealTimeMessage message)
{
 // do domething
}
static void Main(字符串[]args)
{
列表消息=GetRealTimeMessage();
Parallel.ForEach(消息,(消息)=>
{
processMessage(消息);
});
Console.ReadLine();
}
私有静态异步void processMessage(RealTimeMessage)
{
尝试
{
while(true)
{
等待任务延迟(时间跨度从秒(60));
等待任务。运行(()=>ProceesRequest(消息));
}
}
捕获(例外)
{
Console.WriteLine(“严重错误”);
}
}
私有静态列表GetRealTimeMessage()
{
List realTimeMessages=新列表();
添加(新的RealTimeMessage{MessageText=“message4”,IntervalTime=“1”,MessageType=“AIDX”,TimeOfDay=”“});
添加(新的RealTimeMessage{MessageText=“Message 5”,IntervalTime=“2”,MessageType=“AMSX”,TimeOfDay=”“});
返回实时消息;
}
私有静态无效过程请求(RealTimeMessage)
{
//做事
}
  • 这是对
    并行的误用。对于每个
    任务,请使用
    任务。当所有
    任务
  • 不要在ProcessMessage中启动
    任务
    (这可能是故意的,但看起来像是个错误)
  • 使用
    CancellationToken
    取消任务
  • 除非用于事件,否则不要使用
    async void
  • 方法名称使用标准大小写
  • 不要在(!token.IsCancellationRequested)时使用
    while(true)
    use
    while(!token.IsCancellationRequested)
  • 当考虑到所有的事情时,它看起来是这样的

    static async Task Main(string[] args)
    {
       var ts = new CancellationTokenSource();
    
       var messages = GetRealTimeMessage();
       var tasks = messages.Select(x => ProcessMessage(x, ts.Token));
    
       Console.WriteLine("Press any key to cancel tasks")
       Console.ReadKey();
    
       ts.Cancel();
       await Task.WhenAll(tasks);
    
       Console.WriteLine("All finished");
       Console.ReadKey(); 
    }
    
    private static async Task ProcessMessage( RealTimeMessage message, CancellationToken token )
    {
       try
       {
          while (!token.IsCancellationRequested)
          {
             await Task.Delay(TimeSpan.FromSeconds(60), token);
             ProcessRequest(message);
          }
       }
       catch (OperationCanceledException)
       {
          Console.WriteLine("Operation Cancelled");
       }
       catch (Exception ex)
       {
          Console.WriteLine("Critical error: " +  ex.Message);
       }
    }
    

    要取消任务,只需调用
    ts.cancel()

    为什么要在while循环中启动任务?要在每60秒延迟后运行一个方法,延迟时间可能会有所不同,我是说它是可配置的。当我不编写它时,在循环中它会完成所有任务,但我希望在每60秒后运行我的方法,它的行为应该像一个调度器。@radhey_mishra它以60的延迟重复运行ProcessRequest,直到它被取消调试,然后从以下位置退出:wait Task.delay(TimeSpan.FromSeconds(60),token)@radhey_mishra您只能使用令牌一次。然后你必须创建一个新的。当我为下一次运行提供60秒的延迟时,
    Task.Delay
    将退出函数,没有其他原因…它将进入睡眠模式并退出。