我有一个多线程程序,它打开几个线程来查询外部 CRM,并将结果保存在内存中的 IDictionary 中,以加快系统速度。
我对多线程和临界区有点困惑。我希望我的类 QueryThreadProcess
有一个运行查询并管理启动和停止查询的线程。它有一个查询类型的对象,并将结果保存在列表中。
QueryManager
类将终止所有进程或启动所有进程,基本上是集合范围的方法。
我有一种感觉,QueryThreadProcess
的私有(private)成员在所有线程之间共享。我怎样才能使它们对每个线程都是私有(private)的,同时又能从外部类中单独杀死每个线程?
我不想锁定,因为我希望所有线程并行运行。
这是我的经理类:
public class QueryManager
{
private IDictionary<int, QueryThreadProcess> _queries;
public QueryManager()
{
_queries = new Dictionary<int, QueryThreadProcess>();
}
public void Start()
{
CreateQueryThreadsFromDb();
StartAllThreads();
}
private void StartAllThreads()
{
if (_queries != null && _queries.Count > 0)
{
StopThreadsAndWaitForKill();
}
foreach (var query in _queries)
query.Value.Start();
}
private void CreateQueryThreadsFromDb()
{
var queries = new QueryProvider().GetAllQueries();
if (_queries != null && _queries.Count > 0)
{
StopThreadsAndWaitForKill();
_queries.Clear();
}
foreach (var query in queries)
_queries.Add(query.Id, new QueryThreadProcess(query));
}
private void StopThreadsAndWaitForKill()
{
KillAllThreads();
while (!AreAllThreadsKilled()) { }
}
private void KillAllThreads()
{
foreach (var query in _queries)
query.Value.Kill();
}
private bool AreAllThreadsKilled()
{
return _queries.All(query => query.Value.IsKilled);
}
public IList<User> GetQueryResultById(int id)
{
return _queries[id].Result;
}
}
这是我的 QueryProcesses 类,它包含执行实际查询的线程:
using System.Collections.Generic;
using System.Threading;
using Intra.BLL.MessageProviders;
using Intra.BO;
using Intra.BO.Messages;
namespace Intra.BLL.QueryProcess
{
internal class QueryThreadProcess
{
private readonly Thread _thread;
private readonly Query _query;
private bool _isStoppingQuery = false;
private bool _isKilled = true;
private IList<User> _result;
private readonly object _objSync = new object();
public QueryThreadProcess(Query query)
{
_query = query;
_thread = new Thread(RetrieveQueries);
}
public void Start()
{
_isStoppingQuery = true;
while (!_isKilled) { }
_isStoppingQuery = false;
_thread.Start();
}
private void RetrieveQueries()
{
const string BROKERNAME = "bla";
_isKilled = false;
while (!_isStoppingQuery)
{
Broker broker = new BrokerProvider().GetBrokerByName(BROKERNAME);
var users = new QueryProvider().GetUserObjectsByQuery(_query, ParaTokenGenerator.GetBrokerAuthToken(broker));
_result = users;
}
_isKilled = true;
}
public bool IsKilled
{
get { return _isKilled; }
}
public IList<User> Result
{
get
{
lock (_objSync)
return _result;
}
}
public void Kill()
{
_isStoppingQuery = true;
}
}
}
最佳答案
它并没有真正回答你的问题,但它看起来像是一种使用 Task Parallel Library 的更现代的方法。 .NET 4 可以让您省去一些麻烦。不需要自己控制线程。看起来您可以将您的类重构为几行代码并摆脱所描述的问题。
关于c# - 如何在多线程环境中保持对象成员变量对线程私有(private),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8339342/