我一直在尝试创建一个通用的worker / thread类,它接受一个专门包含一长串程序步骤的方法.我们的想法是能够以类似于在Visual Studio中设置断点以暂停/取消暂停的方式暂停/恢复它.为了提供上下文,我主要使用ASP.NET和XAML WPF接口(目前是XAML)进行自动化.
我的理解是我需要使用某种代表,但我正在寻找一个简单的英语简单示例.我发现的示例是完全不同的范围,我很难跟踪其他环境中提供的解决方案.
从MSDN和Stackoverflow上的其他示例来看,到目前为止,“Task”工作类是我所拥有的,但是我对DoDelegatedMethod和构造函数的位置有点不知所措.我在这里要做的是实例化一个Task对象,在新的实例化上传递一个委托方法,创建一个新线程,并将传入的方法与该线程结合.
我之所以想要一般的“任务”,是因为我可以一般地管理特定的方法,而不必为每个实例编写不同的“DoWork”方法.
这是正确的方法吗?
class Task { private ManualResetEvent _shutdownFlag = new ManualResetEvent(false); private ManualResetEvent _pauseFlag = new ManualResetEvent(true); private delegate void MyDelegate(); Thread _thread; public Task() { } public Task(MyDelegate d = new MyDelegate(DoStuff)) // ERROR { _thread = new Thread(DoDelegatedMethod); // ERROR } public void Start() { _thread.Start(); } public void Resume() { _pauseFlag.Set(); ; } public void Stop() { _shutdownFlag.Set(); _pauseFlag.Set(); _thread.Join(); } private void DoDelegatedMethod(MyDelegate d) { do { d(); } while (!_shutdownFlag.WaitOne(0)); } // This does nothing but spin forever until I force it to stop public void Spin() { do { // MessageBox.Show("test"); _pauseFlag.WaitOne(Timeout.Infinite); } while (!_shutdownFlag.WaitOne(0)); //MessageBox.Show("thread over"); } }
解决方法
ThreadStart method = new ThreadStart(() => DoDelegatedMethod(d)); _thread = new Thread(method);
这会创建一个匿名回调(()=> DoDelegatedMethod(d)位),在运行时将使用委托d调用DoDelegatedMethod(由anonmyous方法“捕获”).现在你将这个匿名回调传递给Thread构造函数,所以当线程运行时,它将调用匿名回调,然后调用DoDelegatedMethod(d).实际上,lambda将DoDelegatedMethod调整为ThreadStart签名.
另一种方法是将DoDelegatedMethod更改为不带参数,并将d存储为DoDelegateMethod将访问的Task类的成员字段.
此外,构造函数出错的原因是默认值只能是有限的一组类型,而委托不是其中之一(只有属性允许的类型,如int,long,string和Type是允许的).改为使用过载:
public Task() : this(new MyDelegate(DoStuff)) { ... } public Task(MyDelegate d) { ... }
请注意,如果DoStuff是Task的实例方法,您仍可能会收到错误 – 它不清楚.我个人认为让Task运行的默认委托是一个奇怪的设计,所以你可能只想摆脱默认的构造函数.
在评论中讨论后,我认为值得总结一下Task类的建议修订:
public class Task { private readonly Action _action; // other members as before // default constructor removed public Task(Action action) { _action = action; } public void Start() { ThreadStart ts = new ThreadStart(DoDelegatedMethod); _thread = new Thread(ts); _thread.Start(); } private void DoDelegatedMethod() { do { _action(); } while (!_shutdownFlag.WaitOne(0)); } // other members as before }
用法:
Task task = new Task(this.AutomatedTasks); task.Start(); private void AutomatedTasks() { ... }