首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >背景线程的取消模式

背景线程的取消模式
EN

Stack Overflow用户
提问于 2009-08-28 07:00:41
回答 4查看 840关注 0票数 1

我的代码运行在后台线程中,需要定期检查用户是否希望中止工作。

问题是如何在基本稳定的环境中实现这一点。

  • 是我插入到每个类中的ICancel接口.
  • 是一个公共静态成员,位于

的某个位置

非限定性似乎总是迟早会产生问题。另一方面,“标准”注射的数量正在稳步增长(ILogger,IProgressReporter,.)因此,简单的事情,如取消,可能是很好的候选使用静态。

还有其他/更好的方法吗?有什么经验可以分享吗?

我正在使用WPF和C#,但问题是一般性的。

下面是一个示例:

代码语言:javascript
复制
// this code is in some model assembly

public class BackgroundWorkFactory {
    public IDoingBackgroundWork Worker { 
        get { return new DoingBackgroundWork(new Whatever()); }
    }

internal class DoingBackgroundWork : IDoingBackgroundWork {
    public DoingWork(IWhatever whatever) {
        mWhatever = whatever;
    }
    public void WorkThatCanBeCanceled() {
        while (!Canceled && somethingElse) {
            mWhatever = whatever.DoSomthingElseThatMightAlsoAllowCancel();
            ...
        }
    }
}


// This code is in the GUI Assembly

public void StartWork() {
    IDoingBackgroundWork work = factory.Worker;
    Thread t = new Thread(work->WorkThatCanBeCanceled());
    t.Start();
}

public void StopWork() {
   // ??
}
EN

回答 4

Stack Overflow用户

发布于 2009-08-28 07:08:56

您也可以简单地在每个类中创建一个名为volatileUserHasWork标志,这个标志将在正确的时候运行。如果用户取消,请检查标志并停止线程。

然而,这不能在接口中使用,但是我确实发现它是执行您想要的内容的一种有用的方法。您也可以在抽象类中使用它,但是这种方法的优点大于优点。

票数 0
EN

Stack Overflow用户

发布于 2009-08-28 07:12:59

IIUC,您建议静态的方法是取消所有后台线程。我觉得这还不够模块化,每个线程都应该单独取消。

OTOH,一个单独的ICancel接口不允许大量的重用。我会提议上一节课

代码语言:javascript
复制
class CancelThread{
  private boolean cancelled;
  synchronized void cancel(){cancelled = true;}
  synchronized boolean isCancelled(){return cancelled}
}

每个线程都有一个这样的对象,而且可能还有一个全局集合,其中有许多这样的对象。因此,要取消所有线程,您可以在集合上迭代,并对每个线程调用cancel。

票数 0
EN

Stack Overflow用户

发布于 2009-08-28 08:28:53

也许我在这里有点迷路了,但是为什么IDoingBackgroundWork不能声明一个简单的Cancel方法,这个方法将在基类DoingBackgroundWorkerBase中实现呢?

这样,您就可以简单地取消调用方的工作线程、默认实现和修改该实现的能力。真的有必要用注射剂吗?我认为旧的好的“简单”的OO模式是正确的。

更新:

那我就不喜欢这两种方法。IWhatever需要知道他必须在某个时候优雅地停止,所以您不能只是插入代码并期望它感激地退出,静态类将添加相同级别的耦合(这意味着IWhatever必须知道并使用该静态类)。

我会定义一个ICancelable接口,然后执行:

代码语言:javascript
复制
class DoingBackgroundWorkBase
{
  public Cancel()
  {
    ICancelable cancelableWork = mWhatever as ICancelable;
    if (cancelableWork != null)
      cancelableWork.Cancel();
    else
      this.Abort();
  }  
}

当然还有

代码语言:javascript
复制
IDoingBackgroundWork work = factory.Worker;
work.Start();

因此,IDoingBackgroundWork负责手动启动线程(或者可能是线程本身),并为IWhatever不实现ICancelable时提供“优雅的”类型的退出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1345456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档