Прежде всего:
Пожалуйста, не используйте
mysql_*
функции в новом коде . Они больше не поддерживаются и официально устарели . См. Красную рамку ? Узнайте о подготовленных операторах и используйте PDO или MySQLi - в этой статье , которые помогут вам решить, какой из них. Если вы выберете PDO, вот хороший учебник .Это происходит, когда вы пытаетесь получить данные из результата
mysql_query
, но запросЭто предупреждение и не остановит скрипт, но сделает вашу программу неправильной.
Вам нужно проверить результат, возвращенный
mysql_query
, на$res = mysql_query($sql); if (!$res) { die(mysql_error()); } // after checking, do the fetch
Вопросы, относящиеся
- mysql_fetch_array () ожидает, что параметр 1 будет ресурсом, логическим значением в select
- Все «mysql_fetch_array () ожидает, что параметр 1 будет ресурсом, boolean задан« Вопросы по Stackoverflow
Связанные ошибки:
Другие функции
mysql*
, которые также ожидают, что ресурс результата mysql в качестве параметра приведет к той же ошибке для такой же причина.
Одно различие то, что 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
являются способом пойти.
Я думаю Поток. Сон прекрасен, если Вы действительно хотите приостановить приложение для указанного количества времени. Я думаю причина, люди говорят, что это - плохой дизайн, то, потому что в большинстве ситуаций люди на самом деле не хотят, чтобы приложение приостановилось.
, Например, я работал над pop3 клиентом, где программист использовал Поток. Сон (1000) для ожидания, в то время как сокет полученная почта. В той ситуации было лучше поднять трубку обработчик событий к сокету и продолжающемуся выполнению программы после того, как сокет завершился.
Единственная говядина, которую я имею с Системой. Таймер - то, что большую часть времени я видел, что это использовало для длительных задержек (часы, минуты) в опросе сервисов, и разработчики часто забывают запускать событие Прежде , они запускают таймер. Это означает, что, если я запускаю приложение или сервис, я должен ожидать, пока таймер не протекает (часы, минуты), прежде чем это на самом деле выполнится.
Несомненно, это не проблема с таймером, но я думаю что его часто используемый неправильно потому что его просто слишком легкий неправильно использовать.
использовать 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);
@miniscalope Нет, не используйте ThreadPool.RegisterWaitForSingleObject вместо таймера, System.Threading.
Я помню, как реализовал решение, подобное решению Эрика. Однако это рабочий;)
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; }
}