【问题标题】:How to avoid modified closures with ThreadStart如何避免使用 ThreadStart 修改闭包
【发布时间】:2014-05-23 16:36:52
【问题描述】:

我在 Resharper 中收到“访问修改后的闭包”错误。有没有办法将任务作为参数传递给 lambda 而不是依赖闭包?

        while (!Quitting && TaskQueue.Any())
        {
            foreach (var task in TaskQueue.ToArray())
            {
                if (Quitting || task.Code == TaskCode.Quit)
                {
                    Quitting = true;
                    return;
                }
                if (!task.Runnable)
                {
                    continue;
                }

                var thread = new Thread(() =>
                {
                    try
                    {
                        task.Callback();
                    }
                    catch (Exception e)
                    {
                        if (task.Error != null)
                        {
                            task.Error(e);
                        }
                    }
                });
                thread.Start();

            }

        }

【问题讨论】:

    标签: c# multithreading lambda closures resharper


    【解决方案1】:

    您可以使用Thread.Start(object state) 方法:

    while (!Quitting && TaskQueue.Any())
    {
        foreach (var task in TaskQueue.ToArray())
        {
            if (Quitting || task.Code == TaskCode.Quit)
            {
                Quitting = true;
                return;
            }
            if (!task.Runnable)
            {
                continue;
            }
    
            var thread = new Thread(state =>
            {
                var taskState = (Task)state;
                try
                {
                    taskState.Callback();
                }
                catch (Exception e)
                {
                    if (taskState.Error != null)
                    {
                        taskState.Error(e);
                    }
                }
            });
    
            thread.Start(task);
        }
    }
    

    这相当于使用一个单独的函数:

    private void Process(object state)
    {
        var task = (Task)state;
        try
        {
            task.Callback();
        }
        catch (Exception e)
        {
            if (task.Error != null)
            {
                task.Error(e);
            }
        }
    }
    

    你会这样通过的:

    while (!Quitting && TaskQueue.Any())
    {
        foreach (var task in TaskQueue.ToArray())
        {
            if (Quitting || task.Code == TaskCode.Quit)
            {
                Quitting = true;
                return;
            }
            if (!task.Runnable)
            {
                continue;
            }
    
            new Thread(this.Process).Start(task);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 2017-07-07
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多