如何使用带有接口的 child class 委托的事件处理程序
How to use event handler with delegate from child class with interface
我在这里进行了一些搜索,但未能得到我的问题的明确答案。
我有几个 child classes 都有 1 个接口。我有一个 parent class 包含一个变量,这个变量是根据外部参数创建的 child classes 之一的新实例。这是一些代码:
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
函数。在此函数中,我将调用事件处理程序。在 C1/C2/C3 classes 中,当后台 worker 完成执行时,我会调用此方法。完美运行。我们正在升级到 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
}
}
这里的关键点是在您的管理器中正确分配执行处理程序,然后使用它来订阅 C1 class 事件。在 C1 class 中,为 DoStuff 使用一个 Task,并在 Execute 中等待它成为一个异步任务。一旦 DoStuff
完成,WorkerCompleted 任务就会运行,执行您的处理程序,然后您就可以开始了。
这都可以稍微简化,但这超出了这个问题的范围。这个想法是控制流将如何工作,并使用带有等待的异步调用来确保您的程序等待它需要的东西,然后继续,以及您如何在外部订阅该事件。
一定要在外面等待您的 MyManager.doStuff 电话,否则您等待的任何结果都不会及时得到。
我在这里进行了一些搜索,但未能得到我的问题的明确答案。 我有几个 child classes 都有 1 个接口。我有一个 parent class 包含一个变量,这个变量是根据外部参数创建的 child classes 之一的新实例。这是一些代码:
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
函数。在此函数中,我将调用事件处理程序。在 C1/C2/C3 classes 中,当后台 worker 完成执行时,我会调用此方法。完美运行。我们正在升级到 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
}
}
这里的关键点是在您的管理器中正确分配执行处理程序,然后使用它来订阅 C1 class 事件。在 C1 class 中,为 DoStuff 使用一个 Task,并在 Execute 中等待它成为一个异步任务。一旦 DoStuff
完成,WorkerCompleted 任务就会运行,执行您的处理程序,然后您就可以开始了。
这都可以稍微简化,但这超出了这个问题的范围。这个想法是控制流将如何工作,并使用带有等待的异步调用来确保您的程序等待它需要的东西,然后继续,以及您如何在外部订阅该事件。
一定要在外面等待您的 MyManager.doStuff 电话,否则您等待的任何结果都不会及时得到。