Я обычно - сторонник помещения всего в хранимых процедурах по всем причинам, на которых DBAs были harping в течение многих лет. В случае Linq это верно, что не будет никакого различия в производительности с простыми запросами CRUD.
, Но имеют в виду несколько вещей при принятии этого решения: использование любого ORM связывает Вас плотно с Вашей моделью данных. DBA не имеет никакой свободы внести изменения в модель данных, не вынуждая Вас изменить Ваш скомпилированный код. С хранимыми процедурами можно скрыть эти виды изменений до степени, так как список параметров и набор (наборы) результатов, возвращенный из процедуры, представляют свой контракт, и внутренности могут переехаться, настолько долго поскольку тот контракт все еще выполняется.
И также, если Linq используется для более сложных запросов, настраивая базу данных, становится намного более трудной задачей. Когда хранимая процедура отстает, DBA может полностью сфокусироваться на коде в изоляции и имеет много опций, именно так тот контракт все еще удовлетворен, когда он сделан.
я видел многих, много случаев, где серьезные проблемы в приложении были решены изменениями в схеме и коде в хранимых процедурах без любого изменения в развернутом, скомпилированном коде.
, Возможно, гибридный подход был бы любезен с Linq? Linq может, конечно, использоваться для вызова хранимых процедур.
Вы можете позволить таймер продолжит запускать метод обратного вызова, но оберните нереентерабельный код в Monitor.TryEnter / Exit. В этом случае нет необходимости останавливать / перезапускать таймер; перекрывающиеся вызовы не будут получать блокировку и немедленно возвращаться.
private void CreatorLoop(object state)
{
if (Monitor.TryEnter(lockObject))
{
try
{
// Work here
}
finally
{
Monitor.Exit(lockObject);
}
}
}
Пара возможных решений:
Вы можете управлять вариантом №2 без удаления / создания нового объекта, используя метод Change ()
исходного объекта таймера, но я не уверен, каково именно поведение вызов Change ()
с новым тайм-аутом начала после истечения первого тайм-аута. Это стоило бы одного или двух тестов.
Изменить:
Я провел тест - управление таймером как перезапускаемым однократным запуском, похоже, работает отлично, и это намного проще, чем другие методы. Вот пример кода, основанного на вашем, в качестве отправной точки (некоторые детали могли быть изменены, чтобы заставить его скомпилировать на моей машине):
private Timer _creatorTimer;
// BackgroundWorker's work
private void CreatorWork(object sender, EventArgs e) {
// note: there's only a start timeout, and no repeat timeout
// so this will fire only once
_creatorTimer = new Timer(CreatorLoop, null, 1000, Timeout.Infinite);
// some other code that worker is doing while the timer is active
// ...
// ...
}
private void CreatorLoop(object state) {
Console.WriteLine( "In CreatorLoop...");
/*
... Work here
*/
Thread.Sleep( 3000);
// Reenable timer
Console.WriteLine( "Exiting...");
// now we reset the timer's start time, so it'll fire again
// there's no chance of reentrancy, except for actually
// exiting the method (and there's no danger even if that
// happens because it's safe at this point).
_creatorTimer.Change(1000, Timeout.Infinite);
}
У меня была аналогичная ситуация с System.Timers.Timer, где прошедшее событие выполняется из пула потоков и требует повторного входа.
Я использовал этот метод, чтобы обойти проблема:
private void tmr_Elapsed(object sender, EventArgs e)
{
tmr.Enabled = false;
// Do Stuff
tmr.Enabled = true;
}
В зависимости от того, что вы делаете, вы можете рассмотреть System.Timers.Timer, вот хорошее резюме из MSDN
System.Windows.Forms System.Timers System.Threading
Timer event runs on what thread? UI thread UI or worker thread Worker thread
Instances are thread safe? No Yes No
Familiar/intuitive object model? Yes Yes No
Requires Windows Forms? Yes No No
Metronome-quality beat? No Yes* Yes*
Timer event supports state object? No No Yes
Initial timer event can be scheduled? No No Yes
Class supports inheritance? Yes Yes No
* Depending on the availability of system resources (for example, worker threads)