繁体   English   中英

如何使用带有接口的子 class 委托的事件处理程序

[英]How to use event handler with delegate from child class with interface

我在这里做了一些搜索,但无法明确回答我的问题。 我有几个子类都有 1 个接口。 我有一个父 class 包含一个变量,并且该变量根据外部参数创建为这些子类之一的新实例。 这是一些代码:

public interface I
{
    public delegate void ExecutionCompletedHandler(bool status);
    public event ExecutionCompletedHandler executionCompleted;
    public void Execute();
}

public class C1 : I
{
    public void Execute()
    {
        // Create background worker and execute DoStuff
    }

    public void BackgroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        bool status = (bool)e.Result;
        this.executionCompleted(true);
    }
}

public class C2 : I
{
    // Same setup as C1
}

public class C3 : I
{
    // Same setup as C1
}

public class MyManager
{
    public void doStuff(int val)
    {
        var compObj = null;
        // compObj is now instantiated as new instance of C1, C2 or C3 depending on val
        // ex: compObj = new C1();

        compObj.executionCompleted += new I.ExecutionCompletedHandler(executionCompletedHandler);
        compObj.Execute();
    }

    private void executionCompletedHandler(bool status)
    {
        // Do stuff with status and exit gracefully
    }
}

这是我想做的,但我知道这是不对的。 我觉得好像我已经完成了 90% 的路。 就是说 C1 class 中的 executionCompleted 变量隐藏了接口的变量。 我尝试遵循各种指南和示例,但无法弄清楚这一点。 谢谢!

编辑:我在 Visual Studio 2010 中使用 .NET 4.0。

编辑 2:我在@NikProtsman 的帮助下能够弄清楚...我将接口转换为抽象 class,并在该抽象 class 中实现了CompleteExecution ZC1C425268E68385D1AB5074C17ZA4。 在这个 function 中,我将调用事件处理程序。 在 C1/C2/C3 类中,当后台工作人员执行完毕后,我会调用此方法。 完美运行。 我们正在升级到 VS 2019 的过程中,在此之后,我将推动它更快地实现! 谢谢!

尝试这个:

在您的界面中,将执行更改为:

public Task Execute();

在您的 Class C1 中:

//Add this line to conform to Interface
public event I.ExecutionCompleteHandler executionCompleted;

public async Task Execute()
{
    // Create background worker and execute DoStuff
    await DoStuff();
    // You'll need to supply appropriate args here
    BackgroundWorkerCompleted(this, args);
}

public void BackgroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    bool status = (bool)e.Result;
    //Changed this line, assumed you needed the status from the line above
    executionCompleted?.invoke(status);
}

接下来你的 MyManager 应该是这样的:

public class MyManager
{
    public async Task doStuff(int val)
    {
        var compObj = null
        // compObj is now instantiated as new instance of C1, C2 or C3 depending on val
        compObj = new C1();

        // Subscribe to the 'executioncompleted' event in your new instance
        compObj.executionCompleted += HandleExecutionComplete;
        // Execute your code
        await compObj.Execute();
        // Unsubscribe from the event (cleaning up after yourself)
        compObj.executionCompleted -= HandleExecutionComplete;
    }

    private void HandleExecutionComplete(bool status)
    {
        // Do stuff with status and exit gracefully
    }
}

这里的关键点是在你的 Manager 中正确分配 Execution Handler,然后使用它来订阅 C1 class 事件。 在 C1 class 内部,为 DoStuff 使用一个任务,并在 Execute 中等待它成为一个异步任务。 一旦DoStuff完成,WorkerCompleted 任务就会运行,执行您的处理程序,然后关闭 go。

这一切都可以稍微简化,但这不在此问题的 scope 范围内。 这个想法是控制流将如何工作并使用带有等待的异步调用来确保您的程序等待它需要的东西,然后继续,以及您如何在外部订阅该事件。

请务必在外面等待您的 MyManager.doStuff 调用,否则您等待的任何结果都不会及时得到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM