微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何使用委托在线程包装器类中传递方法?

我现在正在自学C#并且我在编程方面有点新,所以如果在另一个主题(我尝试搜索)中有所涉及,请提前道歉.

我一直在尝试创建一个通用的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");
    }
}

解决方法

新的Thread()接受一个ThreadStart(或ParameterisedThreadStart)参数,而你的DoDelegatedMethod回调没有ThreadStart的正确签名.所以你需要写这样的东西:
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() { ... }

原文地址:https://www.jb51.cc/csharp/100421.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐