Сравните Поток использования. Сон и Таймер для задержанного выполнения

Предупреждение: mysql_fetch_array () ожидает, что параметр 1 является ресурсом, boolean given

Прежде всего:

Пожалуйста, не используйте mysql_* функции в новом коде . Они больше не поддерживаются и официально устарели . См. Красную рамку ? Узнайте о подготовленных операторах и используйте PDO или MySQLi - в этой статье , которые помогут вам решить, какой из них. Если вы выберете PDO, вот хороший учебник .


Это происходит, когда вы пытаетесь получить данные из результата mysql_query, но запрос

Это предупреждение и не остановит скрипт, но сделает вашу программу неправильной.

Вам нужно проверить результат, возвращенный mysql_query, на

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

Вопросы, относящиеся

Связанные ошибки:

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

56
задан akjoshi 7 December 2017 в 15:45
поделиться

6 ответов

Одно различие то, что System.Threading.Timer отправки обратный вызов на потоке пула потоков, вместо того, чтобы создать новый поток каждый раз. При необходимости в этом для случая несколько раз во время срока действия приложения, это сохранит издержки создания и уничтожения набора потоков (процесс, который является очень интенсивно использующим ресурсы как статья Вы контрольные точки), так как это просто снова использует потоки в пуле, и если у Вас будет больше чем один таймер, идущий сразу, это означает, что у Вас будет меньше потоков, работающих сразу (также сохраняющий значительные ресурсы).

, Другими словами, Timer будет намного более эффективным. Это также может быть более точно, с тех пор Thread.Sleep, как только гарантируют, будет ожидать, ПО КРАЙНЕЙ МЕРЕ, пока количество времени, которое Вы определяете (ОС может поместить его для сна для намного дольше). Предоставленный, Timer все еще не будет точно точным, но намерение состоит в том, чтобы запустить обратный вызов максимально близко к требуемому времени, тогда как это - НЕ обязательно намерение Thread.Sleep.

Что касается уничтожения эти Timer, обратный вызов может принять параметр, таким образом, можно быть в состоянии передать Timer сам, поскольку параметр и вызов Располагают в обратном вызове (хотя я не попробовал это - я предполагаю, что возможно, что Таймер мог бы быть заблокирован во время обратного вызова).

Редактирование: Нет, я предполагаю, что Вы не можете сделать этого, так как необходимо определить параметр обратного вызова в Timer конструктор сам.

, Возможно, что-то вроде этого? (Снова, на самом деле не попробовали его)

class TimerState
{
    public Timer Timer;
}

... и запускать таймер:

TimerState state = new TimerState();

lock (state)
{
    state.Timer = new Timer((callbackState) => {
        action();
        lock (callbackState) { callbackState.Timer.Dispose(); }
        }, state, millisecond, -1);
}

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

<час>

Приложение: Как комментатор указал, если action() делает что-то с UI, то использование System.Windows.Forms.Timer является, вероятно, лучшей ставкой, так как это выполнит обратный вызов на потоке UI. Однако, если дело обстоит не так, и это [до 1 113] по сравнению с [1 114], Threading.Timer являются способом пойти.

42
ответ дан T.S. 26 November 2019 в 17:28
поделиться

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

, Например, я работал над pop3 клиентом, где программист использовал Поток. Сон (1000) для ожидания, в то время как сокет полученная почта. В той ситуации было лучше поднять трубку обработчик событий к сокету и продолжающемуся выполнению программы после того, как сокет завершился.

14
ответ дан Shawn 26 November 2019 в 17:28
поделиться

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

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

1
ответ дан StingyJack 26 November 2019 в 17:28
поделиться

использовать ThreadPool.RegisterWaitForSingleObject вместо таймера:

//Wait 5 seconds then print out to console. 
//You can replace AutoResetEvent with a Semaphore or EventWaitHandle if you want to execute the command on those events and/or the timeout
System.Threading.ThreadPool.RegisterWaitForSingleObject(new AutoResetEvent(false), (state, bTimeout) => Console.WriteLine(state), "This is my state variable", TimeSpan.FromSeconds(5), true);
16
ответ дан 26 November 2019 в 17:28
поделиться

@miniscalope Нет, не используйте ThreadPool.RegisterWaitForSingleObject вместо таймера, System.Threading.

0
ответ дан 26 November 2019 в 17:28
поделиться

Я помню, как реализовал решение, подобное решению Эрика. Однако это рабочий;)

class OneTimer
    {
        // Created by Roy Feintuch 2009
        // Basically we wrap a timer object in order to send itself as a context in order to dispose it after the cb invocation finished. This solves the problem of timer being GCed because going out of context
        public static void DoOneTime(ThreadStart cb, TimeSpan dueTime)
        {
            var td = new TimerDisposer();
            var timer = new Timer(myTdToKill =>
            {
                try
                {
                    cb();
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(string.Format("[DoOneTime] Error occured while invoking delegate. {0}", ex), "[OneTimer]");
                }
                finally
                {
                    ((TimerDisposer)myTdToKill).InternalTimer.Dispose();
                }
            },
                        td, dueTime, TimeSpan.FromMilliseconds(-1));

            td.InternalTimer = timer;
        }
    }

    class TimerDisposer
    {
        public Timer InternalTimer { get; set; }
    }
2
ответ дан 26 November 2019 в 17:28
поделиться
Другие вопросы по тегам:

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