繁体   English   中英

在分层应用程序中从后台线程调用

[英]Invoke from background thread in layered application

Windows形成应用程序,在单独的线程中进行繁重的处理。 在处理过程的某个地方,我需要从用户那里获得一些反馈(例如问一些有关向另一台设备的视觉输出的问题)。 如果要在UI层中执行此操作,我将非常乐于使用控件的Invoke并执行此操作。 处理在业务层中完成。 我问业务层中的每个人,没人知道诸如ControlInvokeMainForm等这样的关键字。我如何通知Main表单并获取输入? (事件?还是我缺少一些简单的东西?)

您需要让您的请求从业务层向上传播,然后从您的UI的表示层调用它。

正如您在注释中所建议的,执行此操作的一种方法是使用从业务层触发并由表示层处理的事件,但这取决于您是否希望构建应用程序以在各层之间进行通信使用事件。

我个人的喜好是让各层直接直接进行通信,因此在这种情况下,我将让业务层与表示输入的表示层进行通信,然后表示层会将请求编组到视图(UI )通过Invoke本身。

一种方法是在您的业务层中创建一个事件 ,您可以通过该事件从您的控件/表单代码进行连接。 当您的控件/窗体接收到该事件时,请编组回到调用Invoke / BeginInvoke的UI线程上,以便相应地更新您的控件。

例如,在您的模型代码中:

public class ModelFoo
{
    public event EventHandler SomethingInterestingHappened;
...

调用(或广播)事件时,通常的做法是通过“ On”方法执行此操作( 使调用成为线程安全的 -另请参见this ):

    private void
    OnSomethingInterestingHappened
        ()
    {
        var SomethingInterestingHappenedCopy = SomethingInterestingHappened;
        if (SomethingInterestingHappenedCopy != null)
        {
            // TODO add your event data in the second args here
            SomethingInterestingHappenedCopy (this, EventArgs.Empty);
        }
    }

然后从您的UI线程订阅它,例如:

ModelFoo.SomethingInterestingHappened += SomethingInterestingHappenedHandler;

哪里:

    private void SomethingInterestingHappenedHandler(object sender, EventArgs e)
    {
// You can call if(this.InvokeRequired) here, since 
// you might already be on the UI thread. 
// However from other threads call Invoke/BeginInvoke if wanting 
// to process synchronously/asynchronously depending on what you need and
// you need to update a control object.
            Invoke(new MethodInvoker(delegate
            {...

我发现事件非常有用,因为感觉就像您将UI与模型很好地分离了一样 这些事件也可以在接口上定义,因此UI代码可以与抽象事物进行对话,这意味着您可以在需要时更改基础类型(例如,进行测试)。

暂无
暂无

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

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