如何等待在 UWP 应用中触发 EventHandler?

Posted

技术标签:

【中文标题】如何等待在 UWP 应用中触发 EventHandler?【英文标题】:How to wait for EventHandler being triggered in UWP app? 【发布时间】:2021-01-28 04:07:28 【问题描述】:

我在 UWP 中制作了一个简单的应用程序,但无法触发 EventHandlers...我在 Core.NET 中制作了相同的应用程序,如果我在main 函数的结尾,所以看起来 main 函数的线程在 EventHandler 被触发之前就死了。

在 UWP 中,有没有办法让实例保持活动状态(即:超时),以便有机会触发 EventHandler。

注意:这是问题的一个例子;真正的上下文将发生在网络请求的接收中。

代码如下:

public sealed partial class MainPage : Page

    public MainPage()
    
        this.InitializeComponent();
        test();
    

    private async void test() 

        Client DiscoverClient;
        DiscoverClient = new Client();
        DiscoverClient.DeviceHandler += Client_DeviceHandler;
        await DiscoverClient.DiscoverAsync();
    

    static private void Client_DeviceHandler(object sender, BroadlinkDevice device)
    
        int x = 0;
    

【问题讨论】:

你能说得更具体点吗?你想要 x = 0 例如在调用DiscoverAsync() 之前要执行的事件处理程序?由于有多种方法可以实现您想要的(使用Thread.Sleep(),使用自旋锁等) "x =0" 如果只是一些代码,那么我可以放置一个断点。预期的行为是 DiscoverAsync 搜索网络上的设备,然后为找到的每个设备调用 Client_DeviceHandler。问题是处理程序永远不会被调用。 我无法重现该问题,因为我不清楚客户端类的定义。您能否向我提供有关客户端类的更多详细信息? @YanGu-MSFT 我正在尝试将github.com/kemalincekara/Broadlink.NET 代码中的“设备发现”集成到接收 Web 请求的 UWP Web 服务(部署在 Raspberry 上的 WIn10 IOT Core 上)中。我想在我的手机和家庭网络上的设备之间建立一个自定义桥接...... 也许你可以尝试使用 Deferral 类。添加语句 var deferral = new Deferral(OnTaskCompleted);在 test() 开头并添加语句 deferral.Complete();在测试()结束时。 OnTaskCompleted 是在延迟完成时调用的方法。 【参考方案1】:

而不是使用

await DiscoverClient.DiscoverAsync()

你可以使用

_ = DiscoverClient.DiscoverAsync().Result

这会强制test() 等待DiscoverAsync() 返回。

.Result 只能在返回类型不是void 时使用,所以你可以让DiscoverAsync() 在完成时返回一个布尔值。然后使用丢弃进行赋值,使构造函数阻塞,直到完成DiscoverAsync()

【讨论】:

DiscoverAsync 返回一个任务,因此没有“结果”属性... :-( 有没有办法用任务方法做类似的事情?我尝试了“等待”方法,但确实如此'nt 工作要么...如果有帮助,DiscoveryAsync 的代码位于此处:github.com/kemalincekara/Broadlink.NET 这很奇怪,因为在我的测试中使用await 会在方法完成之前返回,而.Wait() 只会在函数完成后返回,因为这个方法会同步阻塞当前线程。 我不是 EventHandler 方面的专家...也许有一种使用线程的方法?也许一个类似于我用于 UWP 的 Core.NET 版本 exixts 的解决方案?我不必那么漂亮;只需要工作:-) 也许您可以在 ClientSocket_MessageReceived 方法中添加断点并查看应用程序是否进入该方法。如果app进入ClientSocket_MessageReceived方法,需要检查response的值是否为null。【参考方案2】:

我尝试将您评论中提到的库集成到我的 UWP 应用程序中,当调用方法 GetActiveTcpConnections(Network.cs 中的第 60 行)时,它会抛出“拒绝访问”exption。由于该事件 Client_DeviceHandler 不会被触发。请在 github 中查看此 issue(issue#24369)。

本文档展示了如何在 UWP 中使用套接字。您可以参考服务器示例来修改或实现该功能。

https://docs.microsoft.com/en-us/windows/uwp/networking/sockets

【讨论】:

【参考方案3】:

我尝试了互联网上找到的多种方法(有些使用套接字),但我没有找到可行的解决方案...

我最终使用了一种解决方法:循环通过 ip 搜索设备的主机名。由于 IP 仅在我的路由器重新启动时才会更改,因此很少需要发现过程,所以即使它有点重,对我来说也很好:-)

感谢大家的帮助

【讨论】:

以上是关于如何等待在 UWP 应用中触发 EventHandler?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UWP XAML 上将样式触发器设置为路径绑定父状态

如何在 UWP 的后台每天午夜运行一些代码?

切换到其他应用时不会触发 UWP Flyout 的关闭事件

UWP 后台任务 - 应用程序触发器 - 当文件已存在时无法创建文件

在多窗口 UWP 应用中引发和处理事件

处理来自后台任务的 toast 通知动作触发器 - UWP