Многопоточные операции параллельно с тайм-аутом иногда не удается, их трудно отлаживать - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть система:
Приложение dotnet, работающее на сервере, должно собирать информацию об устройствах в очень большой сети (1500-2000 устройств).

Устройства другого типаи производитель, с некоторыми можно связаться через Ssh, некоторые через Snmp, но они всегда находятся в группах одного типа, поэтому мне легко допросить первого и понять, к какому типу они относятся и как им угрожать.

Эта проверка должна выполняться периодически и как можно быстрее, поэтому я использую многопоточность с использованием System.Reactive.

Поскольку я ищу проблемы, может случиться, что конкретная неответьте, и мне нужен тайм-аут, чтобы освободить этот поток и заставить его работать на новом.

В конце я получаю отчет для каждого устройства, разделенного на те, которые работают нормально, и те, кто не работает.и, возможно, возникла ошибка.

Это код, который я использую:

Observable.Defer(source.ToObservable) 
                .ObserveOn(TaskPoolScheduler.Default)
                .SelectMany(it => 
                    Observable.Start(() => DoNetworkCheck(it))
                        .Select(_ => true)
                        .Amb(Observable
                             .Timer(TimeSpan.FromSeconds(15))
                             .Select(_ => false)),

                    (it, result) => new { it, result })

                .Do (x => {

                        Interlocked.Increment(ref num);

                        var log = $"Checked: {x.it.type} - {x.it.ip}, Number {num} of {source.Count} in thread {Thread.CurrentThread.ManagedThreadId}";

                        if(x.result) {
                            log.toLine();
                        } 
                        else
                        {
                            (log + ", timeout: true").toErrLine();
                            exceptions.Enqueue(new Tuple<MacCpe, Exception>(x.it, new Exception($"Observable timeout, {observableTimespan} seconds")));
                        }
                },
                ex => { ex.StackTrace.toErrLine(); }, 
                () => onDone(routers.ToList(), exceptions.ToList())).Wait();

У меня он работает, и он работает почти на всех устройствах, но у меня есть некоторые sстранные случаи, которые я не могу понять.

Каждый раз, из 2000 сетевых устройств, 20-25 будут проходить тайм-аут, они всегда разные, и если я запускаю программу только на тех 20-25, ониответит правильно.
Так что я не думаю, что это проблема с устройствами, а с программой.Когда я смотрю на визуализацию потоков, я вижу, что некоторые потоки застряли и работают по таймауту, но я не могу понять, почему....?

Как узнать, что не так?Есть ли лучший способ сделать это?

...