首页 > 解决方案 > Azure DeviceClient 不会在程序退出时关闭 dotnetty 线程

问题描述

使用 Microsoft.Azure.Devices.Client.DeviceClient .net 框架 4.8 时,关闭应用程序会使多个线程运行。特别是 DotNetty.Common.dll!DotNetty.Common.Concurrency.SingleThreadEventExecutor.PollTask

Microsoft.Azure.Devices 的 1.34.0 和 1.35.0 版本也有同样的问题。我们使用 DeviceClient 是否不当?这是我不理解的异步事情吗?我错过了正确关闭它的电话吗?

从网上的例子来看,我不应该做任何特别的事情,它应该自己关闭它。但是它仍然挂起,目前这是一个紧密的实现。我还没有独立制作,所以我没有重复这个问题,只运行 DeviceClient 代码

当程序退出时,is_running 被设置,程序关闭其他线程。最终我们调用 Environment.Exit(0);

这应该是所有相关代码

private void thread_method()
{
    using (var _deviceClient = DeviceClient.CreateFromConnectionString(connection), TransportType.Mqtt))
    {
        while (is_running)
        {
            var db = new Database(); // roughly an open entity framework connection
            List <class> unprocessed_messages = db.GetUnprocessed();
            List<List<Messages>> processed = breakup_method(unprocessed_messages);
            foreach (var sublist in processed) 
            {

                if (!await SendMessages(sublist , _deviceClient))
                    break;
                // the processed sublist was successful
                db.SaveChanges(); // make sure we dont send again
            }

        }
        Thread.Sleep(500);

        await _deviceClient.CloseAsync();
    }
}
private async Task<bool> SendMessages(List<Message> messages, DeviceClient _deviceClient)
{
    try
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(5000);
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        await _deviceClient.SendEventBatchAsync(messages, cancellationToken);

        if (cancellationToken.IsCancellationRequested)
            return false;
        return true;
    }
    catch (Exception e)
    {
        // logging
    }
    return false;
}

不同的方法,它不会主动发送任何东西。只是一个 open , sleep 直到程序退出,然后关闭,全部在 using 语句中。8 个线程仍在运行 PollTask​​,并且在设置上述所有内容所花费的时间中,是我等待它们关闭的时间。这至少是5分钟。


private void thread_method()
{   
   using (var _deviceClient = DeviceClient.CreateFromConnectionString(connection), TransportType.Mqtt))
    {
       await _deviceClient.OpenAsync();
       while (is_running) Thread.Sleep(500);
       await _deviceClient.CloseAsync();
    }

}

上次更新,独立控制台应用程序。100% 不是我的问题。

// Repost just in case
class Program
{
private static string _connection_string = $"HostName={url};DeviceId={the_id};SharedAccesskey={key}";// fill your in
    public static bool is_running = false;
    static void Main(string[] args)
    {

        is_running = true;
        new System.Threading.Thread(new System.Threading.ThreadStart(thread_method)).Start();
        Console.WriteLine("enter to exit");
        String line = Console.ReadLine();
        is_running = false;
    }
    public static async void thread_method()
    {
        using (var _deviceClient = DeviceClient.CreateFromConnectionString(_connection_string, TransportType.Mqtt))
        {
            await _deviceClient.OpenAsync();
            while (is_running) System.Threading.Thread.Sleep(500);
            await _deviceClient.CloseAsync();
        }
        }
}

https://github.com/Azure/azure-sdk-for-net/issues/24550 撞到正确的位置 https://github.com/Azure/azure-iot-sdk-csharp/issues/2194

标签: c#.netazure

解决方案


https://github.com/Azure/azure-sdk-for-net/issues/24550 https://github.com/Azure/azure-iot-sdk-csharp/issues/2194

不是配置问题,是“dot netty”错误挂起。修复,获取更新的天蓝色版本 Microsoft.Azure.Devices > 1.35.0


推荐阅读