C# C不定式任务循环使用任务类+取消

C# C不定式任务循环使用任务类+取消,c#,.net,multithreading,winforms,task,C#,.net,Multithreading,Winforms,Task,我试图为WinForm项目中的多线程使用创建一个小类 已尝试线程UI问题,BackgroundWorkers的UI也出现了问题,请立即离开:,现在尝试使用任务类。但现在,我不明白如何在类中为所有正在运行的任务创建一个不定式循环和一个取消方法。 我发现的示例将用于1方法中 下面是当前正在工作的part Worker.css的结构和代码,以及WinForm代码中使用的方法 Worker.css 使用于 表格1.cs 所以,它运行了一个示例4个线程,它们执行了,我在日志中得到了J==20,没问题 我的

我试图为WinForm项目中的多线程使用创建一个小类

已尝试线程UI问题,BackgroundWorkers的UI也出现了问题,请立即离开:,现在尝试使用任务类。但现在,我不明白如何在类中为所有正在运行的任务创建一个不定式循环和一个取消方法。 我发现的示例将用于1方法中

下面是当前正在工作的part Worker.css的结构和代码,以及WinForm代码中使用的方法

Worker.css

使用于 表格1.cs

所以,它运行了一个示例4个线程,它们执行了,我在日志中得到了J==20,没问题

我的问题是,如何实现由Worker.doWork方法创建的任务的不定式循环。 以及为Worker类创建一个.Stop方法,该方法在调用时应该停止所有任务。据我所知,这是相关的问题,所以我把它放在1

我尝试了一些解决方案,但都是基于CancellationToken的用法,但我必须仅在Worker.doWork方法中创建此元素,因此我无法使用相同的令牌创建Worker.Stop方法

有人能帮忙吗?线程数量范围我必须在这个软件中使用大约5-200线程。 使用J计算只是用于停止任务/线程的软件工作台的简单条件的一个示例。 在实际情况下,停止条件主要类似于队列完成,或者列表元素清空完成。

最后,让它工作起来

class Worker
{
    public static int threadCount { get; set; }
    Task[] tasks;

    //ex data
    public static string exception;

    static CancellationTokenSource wtoken = new CancellationTokenSource();
    CancellationToken cancellationToken = wtoken.Token;
    public void doWork(ParameterizedThreadStart method)
    {
        try
        {
            tasks = Enumerable.Range(0, 4).Select(i => Task.Factory.StartNew(() =>
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    method(i);
                }
            }, cancellationToken)).ToArray();
        }
        catch (Exception ex) { exception = ex.Message; }
    }


    public void HardStop()
    {
        try
        {
            using (wtoken)
            {
              wtoken.Cancel();
            }
            wtoken = null;
            tasks = null;
        }
        catch (Exception ex) { exception = ex.Message; }
    }
}
但如果我使用此方法退出cancellationToken.ThrowIfCancellationRequested; 获取一个错误: 当作业方法达到J==50,并且调用worker.HardStop函数时,程序窗口崩溃,我获取异常oparencecanceledexception,用户代码未处理异常 在这根绳子上

cancellationToken.ThrowIfCancellationRequested();
那么,怎么了?我已经把它放进了try{}catch{}
据我所知,在wtoken.Cancel上,Task.IsCancelled==false,Task.IsFaulted==true中只应更改一些布尔属性

我会避免所有与任务有关的乱七八糟的事情,并使用微软的反应式框架NuGet Rx Main来实现这一点

以下是方法:

var r = new Random();

var query =
    Observable
        .Range(0, 4, Scheduler.Default)
        .Select(i =>
            Observable
                .Generate(0, x => true, x => x, x => x,
                    x => TimeSpan.FromMilliseconds(r.Next(500, 1000)),
                    Scheduler.Default)
                .Select(x => i))
        .Merge();

var subscription =
    query
        .Subscribe(i => method(i));
如果要取消对方法的调用,请执行以下操作:

subscription.Dispose();
我已经测试过了,效果很好

如果我将其包装到您的worker类中,那么它看起来如下所示:

class Worker
{
    private Random _r = new Random();
    private IDisposable _subscription = null;

    public void doWork()
    {
        _subscription =
            Observable
                .Range(0, 4, Scheduler.Default)
                .Select(n =>
                    Observable
                        .Generate(
                            0, x => true, x => x, x => x,
                            x => TimeSpan.FromMilliseconds(_r.Next(500, 1000)),
                            Scheduler.Default)
                        .Select(x => n))
                .Merge()
                .Subscribe(i => method(i));
    }


    public void HardStop()
    {
        _subscription.Dispose();
    }
}

问题不在于Thread或BackgroundWorker类,而在于您对多线程应用程序的理解。这是一个基础教程,请仔细阅读,确保你理解了核心概念,然后再次处理你的问题。什么是不定式循环?你的意思是无限吗?我已经明白了这一点,并阅读了所有内容,试图在上周解决一个问题。无论如何现在是关于任务,现在是BGworker。问题在于我被描述了。我的意思是,如何在我的情况下实施它。通过不定式循环,我的意思是worker.doWork必须在每个线程中执行一个方法不定式的次数,直到我使用stop方法worker.stop in the Job方法Form1。csi已经明白了这一点,并阅读了所有内容-不,你没有,因为如果你这样做了,你不会调用线程。在你的worker方法中睡眠它只是从其他变体中保留的,忘记删除。对不起,但这与我的问题无关。
subscription.Dispose();
class Worker
{
    private Random _r = new Random();
    private IDisposable _subscription = null;

    public void doWork()
    {
        _subscription =
            Observable
                .Range(0, 4, Scheduler.Default)
                .Select(n =>
                    Observable
                        .Generate(
                            0, x => true, x => x, x => x,
                            x => TimeSpan.FromMilliseconds(_r.Next(500, 1000)),
                            Scheduler.Default)
                        .Select(x => n))
                .Merge()
                .Subscribe(i => method(i));
    }


    public void HardStop()
    {
        _subscription.Dispose();
    }
}