我可以设计此方案的任何无锁解决方案 [英] Can I design any lock-free solution for this scenario

查看:134
本文介绍了我可以设计此方案的任何无锁解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的Employee类如下:

I have a simple Employee class as follows

public class Employee
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
    }

我那么有哪些做的方法,这些员工被称为ProcessThisEmployee的并行处理ProcessEmployees类。在这个方法中,我必须调用第三方库的方法。到目前为止,所有的简单。问题是,当某个用户选择取消该操作时,它在进步,我需要做一些清理那些没有完成的处理还没有任何ThirdPartyLibrary类的实例。请注意,我没有对ThirdPartyLibrary类中的任何控制,它并没有任何机制来消除现有的任务。但它确实提供,我可以在哪里调用SomeAPI尚未完成任何实例调用清洁方法。其结果是,我维持的所有实例的本地目录。当用户选择取消操作,我把我的类CleaupIfUserCancelOperation方法,这个第三方库实例都在我的本地列表的清洁方法。下面是我的code这一点。

I then have a ProcessEmployees class which do concurrent processing of these employees in method called ProcessThisEmployee. Within this method, I have to call a third party library method. So far its all simple. Problem is sometime when user choose to cancel this operation when its in progress, I need to do some clean up on any ThirdPartyLibrary class instances that haven't completed processing yet. Note I don't have any control on the ThirdPartyLibrary class and it does not have any mechanism for cancellation an existing task. It does provide a Clean method that I can call on any instances where call to SomeAPI hasn't finished yet. As a result, I am maintaining an local List of all instances. When user choose to cancel operation, I call CleaupIfUserCancelOperation method of my class that Clean method of this third party library instance that are in the my local list. Below is my code for this.

class ProcessEmployees
{
    private List<Employee> _Employees;
    List<ThirdPartyLibrary> libraries = new List<ThirdPartyLibrary>();
    private object sync = new object();
    public  ProcessEmployees()
    {
        _Employees = new List<Employee>() 
        {
            new Employee() { ID = 1, FirstName = "John", LastName = "Doe" },
            new Employee() { ID = 2, FirstName = "Peter", LastName = "Saul" },
            new Employee() { ID = 3, FirstName = "Mike", LastName = "Sue" },
            new Employee() { ID = 4, FirstName = "Catherina", LastName = "Desoza" },
            new Employee() { ID = 5, FirstName = "Paul", LastName = "Smith" }
        };
    }

    public void StartProcessing()
    {

        Task[] tasks = this._Employees.AsParallel().Select(x => this.ProcessThisEmployee(x)).ToArray();
        Task.WaitAll(tasks);
        // other stuff
    }

    private async Task ProcessThisEmployee(Employee x)
    {
        ThirdPartyLibrary library = new ThirdPartyLibrary();
        lock (sync)
        {
            libraries.Add(library);
        }
        await Task.Factory.StartNew(() => library.SomeAPI(x) );

        lock (sync)
        {
            libraries.Remove(library);
        }
    }

    private void CleaupIfUserCancelOperation()
    {
        foreach (ThirdPartyLibrary library in libraries)
            library.Clean();
    }
}

我要在这里这当然是一个性能命中锁定库实例的两倍。能有可能在这种情况下,可以使用任何重量轻(无锁)机制?我不知道很多有关并发收集,不知道是否这些可能是在这种情况下有什么用处?

I have to lock libraries instance twice in here which of course is a performance hit. Can there be any lightweight (lock-free) mechanism that could be used in this case? I don't know much about the concurrent collection, wonder if those could be of any use in this scenario?

推荐答案

这两个锁呼吁很可能比你正在做的其余部分要少得多的性能影响。假设他们这样做,你可以使用 ConcurrentDictionary 添加和删除实例(你不应该使用一个列表,因为反正现在你在并发库的数量二次性能开销)。

The two lock calls very likely have much less performance impact than the rest you are doing. Assuming they do you can use ConcurrentDictionary to add and remove instances (you shouldn't use a List anyway because right now you have quadratic performance overhead in the number of concurrent libraries).

这可能是更好地使每一个异步方法取消本身和清理自己的东西。通过他们一个的CancellationToken 。使用注册来注册一个回调来清理库。实在是没有必要的全局状态/在这里集合。

It's probably better to make each async method cancel itself and cleanup its own stuff. Pass them a CancellationToken. Use Register to register a callback that cleans up the library. There is really no need for global state/collections here.

这篇关于我可以设计此方案的任何无锁解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆