如何管理线程安全任务的集合

时间:2015-01-17 01:46:14

标签: c# .net multithreading thread-safety

我正在处理一项从API获取任务列表的服务。它获取一个任务列表,每个任务都有一个SQL查询和查询需要运行的频率。

当前的实施

BlockingCollection<QueryRunner> queue = new BlockingCollection<QueryRunner> ();
// Get the list of tasks from an API and serialize them as a Query object.
List<Query> queries = new List<Query>();
dynamic result = _unitOfWork.Get(string.Format("branches/{0}/queries", selectedBranch.id)).Result["queries"];
string json = JsonConvert.SerializeObject(result);
queries = JsonConvert.DeserializeObject<List<Query>>(json, _serializerSettings);

// Query is an object that has an id, a frequency and the SQL text for the
// query.
// QueryRunner is the object that holds the query object and a time
// reference.
foreach (Query query in queries)
{
    QueryRunner queryRunner = new QueryRunner()
    {
        Query = query,
        Branch = _selectedBranch
    };
    queue.Add(queryRunner);
}
queue.CompleteAdding();

// Start processing the queue.
var background = Task.Factory.StartNew(ProcessQueries);

// ProcessQueries body:
int taskCount = 4;
var actions = Enumerable.Repeat<Action> (ProcessQueue, taskCount);
Parallel.Invoke (actions.ToArray ());

// ProcessQueue body:
foreach (QueryRunner queryRunner in _queue.GetConsumingEnumerable()) {
    Query query = queryRunner.Query;
    TimerCallback timerDelegate = new TimerCallback (RunQuery);
    TimeSpan timeSpan = TimeSpan.FromSeconds (query.frequency);
    Timer timer = new Timer (timerDelegate, queryRunner, 0, (int)timeSpan.TotalMilliseconds);
    queryRunner.TimerReference = timer;
}

最后, RunQuery 只执行SQL文本并将结果发送回API。

QueryRunner queryRunner = (QueryRunner)queryObj;
if (!queryRunner.IsWorking)
{
    queryRunner.IsWorking = true;
    // Open connection, run query, get results and send them back to the
    // API.
    queryRunner.IsWorking = false;
}

问题

不完全是一个问题,但现在我需要保留那个队列。

服务必须在一段时间内再次向API请求任务。

新的任务集可能包含也可能不包含相同的查询或更改频率或现有的任务。

我看到BlockingCollection没有公开删除或更新集合中特定项的方法,那么什么是更好的方法呢?

提前致谢。

0 个答案:

没有答案