我有一个服务负责许多任务,其中一个是在一个单独的线程(threadJob子)上启动作业(一次一个),这些作业可能需要相当长的时间和
有各种各样的阶段,我需要报告.
通常,调用应用程序从服务请求状态(GetStatus),这意味着服务需要知道什么时候作业(子线程)是
在,我希望在某些里程碑,子线程可以某种方式通知(SetStatus)其状态的父线程(服务),并且服务可以返回该信息
到调用应用程序.
例如 – 我希望做这样的事情:
class Service { private Thread threadJob; private int JOB_STATUS; public Service() { JOB_STATUS = "IDLE"; } public void RunTask() { threadJob = new Thread(new ThreadStart(PerformWork)); threadJob.IsBackground = true; threadJob.Start(); } public void PerformWork() { SetStatus("STARTING"); // do some work // SetStatus("PHASE I"); // do some work // SetStatus("PHASE II"); // do some work // SetStatus("PHASE III"); // do some work // SetStatus("FINISHED"); } private void SetStatus(int status) { JOB_STATUS = status; } public string GetStatus() { return JOB_STATUS; } };
因此,当需要执行作业时,将调用RunTask()并启动线程(threadJob).这将运行并执行一些步骤(使用SetStatus将新状态设置为
各种要点),最后完成.现在,还有函数GetStatus(),它应该在需要时返回STATUS(来自使用IPC的调用应用程序) – 这个状态
应该反映threadJob运行的作业的当前状态.
所以,我的问题很简单……
threadJob(或更具体地说是PerformWork())如何以线程安全的方式返回Service状态的变化(我假设我的SetStatus / GetStatus上面的例子是
不安全的)?我需要使用活动吗?我假设我不能直接改变JOB_STATUS …我应该使用LOCK(如果是这样的话?)……
解决方法
您可以在Service类中创建一个事件,然后以线程安全的方式调用它.非常关注我如何实现SetStatus方法.
class Service { public delegate void JobStatusChangeHandler(string status); // Event add/remove auto implemented code is already thread-safe. public event JobStatusChangeHandler JobStatusChange; public void PerformWork() { SetStatus("STARTING"); // stuff SetStatus("FINISHED"); } private void SetStatus(string status) { JobStatusChangeHandler snapshot; lock (this) { // Get a snapshot of the invocation list for the event handler. snapshot = JobStatusChange; } // This is threadsafe because multicast delegates are immutable. // If you did not extract the invocation list into a local variable then // the event may have all delegates removed after the check for null which // which would result in a NullReferenceException when you attempt to invoke // it. if (snapshot != null) { snapshot(status); } } }