簡體   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