从阻塞集合中获取结果的正确方法

时间:2019-04-22 16:20:39

标签: c# blockingcollection

我从一个或多个线程中获取了50个IMountCmd对象,并将它们放入一个阻止集合中。每个都执行,并且一些得到结果或错误。它们被放入ConcurrentDictionary中,在其中循环包含ContainsKey并返回对象。这似乎是线程安全且正确的处理阻塞队列的方法吗?

public class CmdGetAxisDegrees : IMountCommand
{
    public long Id { get; }
    public DateTime CreatedUtc { get; private set; }
    public bool Successful { get; private set; }
    public Exception Exception { get; private set; }
    public dynamic Result { get; private set; }
    private readonly AxisId _axis;

    public CmdGetAxisDegrees(long id, AxisId axis)
    {
        Id = id;
        _axis = axis;
        CreatedUtc = HiResDateTime.UtcNow;
        Successful = false;
        Queues.AddCommand(this);
    }

    public void Execute(Actions actions)
    {
        try
        {
            Result = actions.GetAxisDegrees(_axis);
            Successful = true;
        }
        catch (Exception e)
        {
            Successful = false;
            Exception = e;
        }
    }
}

 private static void ProcessCommandQueue(IMountCommand command)
    {
        command.Execute(_actions);
        if (command.Id > 0)
        {
            _resultsDictionary.TryAdd(command.Id, command);
        }
    }

public static IMountCommand GetCommandResult(long id)
    {
        IMountCommand result;
        while (true)
        {
            if (!_resultsDictionary.ContainsKey(id)) continue;
            var success = _resultsDictionary.TryRemove(id, out result);
            if (!success)
            {
                //log 
            }
            break;
        }
        return result;
    }

  static Queues()
    {
        _actions = new Actions();
        _resultsDictionary = new ConcurrentDictionary<long, IMountCommand>();
        _commandBlockingCollection = new BlockingCollection<IMountCommand>();
        Task.Factory.StartNew(() =>
        {
            foreach (var command in _commandBlockingCollection.GetConsumingEnumerable())
            {
                ProcessCommandQueue(command);
            }
        });
    }

public interface IMountCommand
{
    long Id { get; }
    DateTime CreatedUtc { get; }
    bool Successful { get; }
    Exception Exception { get; }
    dynamic Result { get; }
    void Execute(Actions actions);
}

0 个答案:

没有答案