简体   繁体   English

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

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

I've done some searching here and haven't been able to get a clear answer to my problem.我在这里做了一些搜索,但无法明确回答我的问题。 I have a several child classes all with 1 interface.我有几个子类都有 1 个接口。 I have a parent class that contains a variable and this variable is created as a new instances of one of those child classes depending on external params.我有一个父 class 包含一个变量,并且该变量根据外部参数创建为这些子类之一的新实例。 Here's some code:这是一些代码:

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
    }
}

This is what I'd like to do but I know it's not right.这是我想做的,但我知道这是不对的。 I feel as if I'm 90% of the way there.我觉得好像我已经完成了 90% 的路。 It's saying that the executionCompleted variable in the C1 class is hiding the interface's variable.就是说 C1 class 中的 executionCompleted 变量隐藏了接口的变量。 I've tried to follow various guides and examples but haven't been able to figure this out.我尝试遵循各种指南和示例,但无法弄清楚这一点。 Thanks!谢谢!

Edit: I'm using .NET 4.0 in Visual Studio 2010.编辑:我在 Visual Studio 2010 中使用 .NET 4.0。

EDIT 2: I was able to figure it out with help from @NikProtsman...I converted the interface to an abstract class, and in that abstract class, implemented a CompleteExecution function.编辑 2:我在@NikProtsman 的帮助下能够弄清楚...我将接口转换为抽象 class,并在该抽象 class 中实现了CompleteExecution ZC1C425268E68385D1AB5074C17ZA4。 In this function, I would call the event handler.在这个 function 中,我将调用事件处理程序。 In the C1/C2/C3 classes, when background worker is finished executing, I would call this method.在 C1/C2/C3 类中,当后台工作人员执行完毕后,我会调用此方法。 Works perfectly.完美运行。 We're in the process of upgrading to VS 2019 and after this, I'm going to push to make that happen quicker!我们正在升级到 VS 2019 的过程中,在此之后,我将推动它更快地实现! Thanks!谢谢!

Try this:尝试这个:

In your interface, change Execute to:在您的界面中,将执行更改为:

public Task Execute();

In your Class C1:在您的 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);
}

Next your MyManager should look like this:接下来你的 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
    }
}

The key point here is assigning the Execution Handler properly in your Manager, and then using it to subscribe to the C1 class event.这里的关键点是在你的 Manager 中正确分配 Execution Handler,然后使用它来订阅 C1 class 事件。 Inside the C1 class, use a Task for DoStuff, and await it in Execute which becomes an async Task.在 C1 class 内部,为 DoStuff 使用一个任务,并在 Execute 中等待它成为一个异步任务。 Once DoStuff is done, the WorkerCompleted task runs, executes your handler, and off you go.一旦DoStuff完成,WorkerCompleted 任务就会运行,执行您的处理程序,然后关闭 go。

This can all be simplified somewhat but that is outside the scope of this question.这一切都可以稍微简化,但这不在此问题的 scope 范围内。 The idea is how the control flow will work and using async calls with await to make sure your program waits for what it needs, and then continues, and how you subscribe to that event externally.这个想法是控制流将如何工作并使用带有等待的异步调用来确保您的程序等待它需要的东西,然后继续,以及您如何在外部订阅该事件。

Just be sure to await your MyManager.doStuff call on the outside as well, otherwise any results you are waiting for will not get picked up in time.请务必在外面等待您的 MyManager.doStuff 调用,否则您等待的任何结果都不会及时得到。

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

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