Право Вы не были настолько услужливы (обеспечение источника было бы, было действительно полезно!), но здесь Вы идете... Некоторые вещи проверить:
код как это:
<link rel="icon" href="http://www.example.com/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="http://www.example.com/favicon.ico" type="image/x-icon" />
он в <head>
?
действительно ли изображение реально ico файл? (переименование битового массива не является реальным .ico! Мягко другой формат)
это работает, когда Вы добавляете страницу как закладку?
На самом деле это довольно распространенный сценарий. Вы не можете делать что-либо на основе клиента, потому что клиент может уйти и отключиться, и вы потеряете выполненную работу. Решение состоит в использовании Активация компонента Service Broker : вы создаете службу в базе данных и присоединяете активированную процедуру. В своем приложении (или на странице ASP) вы отправляете сообщение службе и встраиваете необходимые параметры для своей процедуры. После того, как ваше приложение зафиксируется, сообщение активирует процедуру обслуживания. сервисная процедура считывает параметры из сообщения и вызывает вашу процедуру. поскольку активация происходит в серверном потоке, не связанном с вашим исходным подключением, это надежно.
Вы можете использовать методы BeginExecuteXXX
/ EndExecuteXXX
(в зависимости от того, возвращает он результат или нет) из SqlCommand
, передача делегата обратного вызова.
Если вы действительно хотите полностью закрыть приложение, я предлагаю вам определить задание в агенте SQL Server и просто выполнить оператор T-SQL, чтобы запустить это задание вручную. Синтаксис:
sp_start_job
{ [@job_name =] 'job_name'
| [@job_id =] job_id }
[ , [@error_flag =] error_flag]
[ , [@server_name =] 'server_name']
[ , [@step_name =] 'step_name']
[ , [@output_flag =] output_flag]
Задание выполнит вашу хранимую процедуру. Вы должны проявить немного изобретательности, чтобы передавать любые аргументы. Например, вставьте параметры в таблицу «очереди» и попросите задание обработать все строки в очереди.
Вместо задания также должен работать триггер вставки в вашей очереди.
Я предлагаю реорганизовать архитектуру. Создайте таблицу «рабочей очереди», в которой вы регистрируете запросы на запуск хранимой процедуры. Затем попросите службу Windows или задание SQL Server время от времени проверять эту рабочую очередь (или проявите изобретательность и используйте триггер), чтобы запустить хранимую процедуру. Пусть хранимая процедура время от времени обновляет ход выполнения в таблице очереди работ, и ваш интерфейсный модуль может смотреть на это и сообщать пользователю о ходе выполнения, а затем отображать результаты, когда они будут выполнены.
Я предпочитаю использовать фоновую службу для автономной обработки, когда ваше пользовательское приложение сообщает службе, что делать, а затем отключается. Служба может регистрировать истекшее время и ошибки / состояние и при необходимости перезапускаться. WCF разработан для этого и поддерживает очереди для связи.
позвольте им закрыть приложение и прийти назад позже
Если вы собираетесь разрешить им полностью закрыть приложение, вам придется запустить отдельный .exe или что-то еще в другом ThreadPool, который выполняет ваш код, вызывая хранимую процедуру . В противном случае ваш поток умрет, когда вы закроете приложение.
Другой способ, который вы могли бы сделать, - разрешить вашему приложению работать в фоновом режиме (возможно, в области уведомлений), а затем выйти или уведомить о завершении задания. Вы можете использовать это, используя методы BeginExecuteNonQuery и EndExecuteNonQuery, чтобы позволить ему работать в отдельном потоке.
Главное окно вашего приложения не обязательно должно быть открыто. Если вы запустили его как вторичный поток, он будет продолжать работать, пока IsBackground == false
. Я обычно предпочитаю делать это через агент SQL Server или в качестве клиент-серверного приложения (ничто не мешает клиент-серверному приложению работать на одном компьютере или даже быть одним и тем же двоичным кодом).
Это было давно ...
using System.Threading;
.....
Thread _t = null;
void StartProcedure()
{
_t = new Thread(new ThreadStart(this.StartProc));
_t.IsBackground = false;//If I remember correctly, this is the default value.
_t.Start();
}
bool ProcedureIsRunning
{
get { return _t.IsRunning; } //Maybe it's IsActive. Can't remember.
}
void StartProc(object param)
{
//your logic here.. could also do this as an anonymous method. Broke it out to keep it simple.
}