Как поймать исключения из ThreadPool. QueueUserWorkItem?

Вам необходимо переопределить функцию IAxisValueFormatter func stringForValue(_ value: Double, axis: AxisBase?) -> String {}.

Как показано ниже:

Шаг 1: настройте свой xAxis с помощью специального средства форматирования.

let xValues = ["X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10"]
let chartFormatter = RadarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter

Шаг 2: Реализация пользовательского форматера с использованием метода ниже.

private class RadarChartFormatter: NSObject, IAxisValueFormatter {

    var labels: [String] = []

    func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        if Int(value) < labels.count {
            return labels[Int(value)]
        }else{
            return String("")
        }
    }

    init(labels: [String]) {
        super.init()
        self.labels = labels
    }
}

Вы получите ниже вывод в вашем RadarCharView:

enter image description here

Надеюсь, это поможет вам получить ваши пользовательские метки на Радиолокационная карта!

44
задан Community 23 May 2017 в 12:32
поделиться

4 ответа

Если у вас есть доступ к действию исходный код, вставьте блок try / catch в этот метод; в противном случае создайте новый метод tryAction , который обернет вызов действия action в блок try / catch.

24
ответ дан Tormod Fjeldskår 26 November 2019 в 21:48
поделиться

Вы можете добавить try / catch следующим образом:

        ThreadPool.QueueUserWorkItem(state =>
                                         {
                                             try
                                             {
                                                 action();
                                             }
                                             catch (Exception ex)
                                             {
                                                 OnException(ex);
                                             }
                                         });
70
ответ дан Prankster 26 November 2019 в 21:48
поделиться

В другом потоке (в методе, который вы «ставите в очередь», добавьте предложение try catch ... Затем в перехвате поместите перехваченное исключение в общую переменную Exception (видимую для основного потока).

Затем в вашем основном потоке, когда все элементы в очереди закончатся (используйте для этого массив дескрипторов ожидания). поток заполнил это общее исключение исключением ... Если это так, перебросьте его или обработайте соответствующим образом ...

вот пример кода из недавнего проекта, для которого я использовал это ...
HasException является общим логическим значением ...

    private void CompleteAndQueuePayLoads(
           IEnumerable<UsagePayload> payLoads, string processId)
    {
        List<WaitHandle> waitHndls = new List<WaitHandle>();
        int defaultMaxwrkrThreads, defaultmaxIOThreads;
        ThreadPool.GetMaxThreads(out defaultMaxwrkrThreads, 
                                 out defaultmaxIOThreads);
        ThreadPool.SetMaxThreads(
            MDMImportConfig.MAXCONCURRENTIEEUSAGEREQUESTS, 
            defaultmaxIOThreads);
        int qryNo = 0;
        foreach (UsagePayload uPL in payLoads)
        {
            ManualResetEvent txEvnt = new ManualResetEvent(false);
            UsagePayload uPL1 = uPL;
            int qryNo1 = ++qryNo;
            ThreadPool.QueueUserWorkItem(
                delegate
                    {
                        try
                        {
                            Thread.CurrentThread.Name = processId + 
                                                      "." + qryNo1;
                            if (!HasException && !uPL1.IsComplete)
                                 IEEDAL.GetPayloadReadings(uPL1, 
                                                  processId, qryNo1);
                            if (!HasException) 
                                UsageCache.PersistPayload(uPL1);
                            if (!HasException) 
                                SavePayLoadToProcessQueueFolder(
                                             uPL1, processId, qryNo1);
                        }
                        catch (MeterUsageImportException iX)
                        {
                            log.Write(log.Level.Error,
                               "Delegate failed "   iX.Message, iX);
                            lock (locker)
                            {
                                HasException = true;
                                X = iX;
                                foreach (ManualResetEvent 
                                          txEvt in waitHndls)
                                    txEvt.Set();
                            }
                        }
                        finally { lock(locker) txEvnt.Set(); }
                    });
            waitHndls.Add(txEvnt);
        }
        util.WaitAll(waitHndls.ToArray());
        ThreadPool.SetMaxThreads(defaultMaxwrkrThreads, 
                                 defaultmaxIOThreads);

        lock (locker) if (X != null) throw X;
    }
3
ответ дан Charles Bretana 26 November 2019 в 21:48
поделиться

Обычно я создаю большой блок try ... catch внутри метода action () затем сохраните исключение как частную переменную и обработайте его в основном потоке

1
ответ дан oscarkuo 26 November 2019 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: