如何从 ConcurrentDictionary 中删除 Thread,当 Thread 完成
本文关键字:Thread 删除 完成 ConcurrentDictionary int | 更新日期: 2023-09-27 17:56:11
这是我的项目要求:
- 承载 WCF 服务的 Windows 服务。
- WCF 服务必须启动并跟踪许多线程。
- 每个线程必须由提供的密钥识别。
- 将有许多不同类型的任务(线程),每个任务都有"一次最大运行时间"限制,队列中的附加任务直到其他相同类型的任务完成。
到目前为止,我拥有的:
- 承载 WCF 服务的 Windows 服务(类似于 http://msdn.microsoft.com/en-us/library/ms733069(v=vs.110).aspx)。
- 一个包含线程的抽象类(使用组合,因为我无法扩展线程)
- 在 WCF 服务类中,我有一个名为 MyThreadPool 的类的静态实例,其中包含一个 ConcurrentDictionary,用于记录正在运行的线程。
我的问题是:
- 从线程列表中删除已完成的线程(线程完成时)的最佳方法是什么?
- 在这种情况下,ConcurrentDictionary 的静态实例是管理线程的好方法吗?如果没有,有什么建议?
我的一些代码如下所示:
[ServiceContract(Namespace = "...")]
public interface IMyService
{
[OperationContract]
void StartProcess(int MIndexId, int MProcessId);
[OperationContract]
void StopProcess(int MIndexProcessId);
}
public class MyService : IMyService
{
private static MyThreadPool threadPool = new MyThreadPool();
public void StopProcess(int MIndexProcessId)
{
throw new NotImplementedException();
}
public void StartProcess(int ItemIdToProcess, int ProcessTypeId)
{
// call threadPool.LaunchThread(...)
}
}
public class MyThreadPool
{
private ConcurrentDictionary<int, BaseThread> _threads;
...
public void LaunchThread(BaseThread thread, int ItemIdToProcess)
{
// set additional data for thread (such as a key and name) for tracking in a database
_threads.AddOrUpdate(ItemIdToProcess, thread, (key, oldValue) => { return oldValue; });
thread.Start();
}
public void KillThread(int ItemIdToProcess)
{
...
}
}
public abstract class BaseThread
{
// some additional properties for tracking thread
// ...
private Thread _thread;
protected BaseThread()
{
_thread = new Thread(new ThreadStart(this.RunThread));
_thread.IsBackground = true;
}
// Thread methods / properties
public void Start() { _thread.Start(); }
public void Join() { _thread.Join(); }
public bool IsAlive { get { return _thread.IsAlive; } }
public string Name
{
get
{
return _thread.Name;
}
set
{
_thread.Name = value;
}
}
public void Abort()
{
_thread.Abort();
}
public abstract void RunThread();
}
public class ValidateThread : BaseThread
{
public override void RunThread()
{
...
// indicate to calling thread to remove from thread list();
}
}
- 使线程在完成所有有意义的工作后自行删除。更好的是,将
Task
与LongRunning
选项一起使用。撰写任务很容易。 - 似乎很合理。您已经避免了很多陷阱,并且设计看起来很扎实。IIS 中承载的 WCF 服务的一个缺陷是工作进程可能随时死亡。您可以通过使用 Windows 服务来避免这种情况。
Windows 服务主要是外部启动的 exe,就像任何其他服务一样。
不过,有一件事是不行的:_thread.Abort();
Thread.Abort 是邪恶的。取消必须(不是:应该)在 .NET 中是合作的。