Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование (VB,C#,ASP,.NET): новости, советы, примеры



Выпуск # 268


http://www.kbyte.ru/

 

Новый выпуск!

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

 

Содержание выпуска

Система ЭКСПЕРТ

    Вопрос #000764: Програмное определение позиции меню в vb6

    Вопрос #000754: HttpWebRequest и HttpWebResponse

    Вопрос #000745: Проблема с компонентом WINSOCK

    Вопрос #000743: C#, forms

    Вопрос #000735: Localization and DataBase

Последнее на форумах

    создать PictureBox

    Всех с 23 февраля!

    Ошибка сохранения в базу

    ASP.NET работа за кадром

    Кодирование -Раскодирование строк

Последние статьи

    Как узнать размер базы данных MySQL через php

    Взаимодействие с другими сайтами через HTTP (HttpWebRequest и HttpWebResponse)

    Работа с SQL – Запросы

    Использование XML.Serialization

    Выбор языка программирования для научных работ (2-я редакция)

Интересные коды и решения

Юмор на Kbyte.Ru

 

Система ЭКСПЕРТ

 

Система «Эксперт» - уникальная система, которая поможет решить, если не все, то многие Ваши проблемы с программированием и разработкой! Если у Вас есть какой-либо вопрос по программированию или разработке, то Вы всегда можете задать его нашим Экспертам! При этом каких-либо особых действий от Вас не потребуется! Просто отправьте Ваш вопрос на адрес mailto:expert@kbyte.ru, в теме письма укажите тему вопроса, в тексте – сам вопрос, и все! Эксперты дадут Вам ответ в течение 12-24 часов, на тот адрес, с которого Вы отправите вопрос. Все проще простого! Никакой регистрации и заполнение бесконечных форм, просто спросите и получите ответ ;-)


Вопрос #000764: Програмное определение позиции меню в vb6

Автор вопроса: Иван Денишев // 16.02.2008 / 23:24

Здравствуйте уважаемые эксперты!
Говорят, что вы можете ответить на любой вопрос.
Как программно в vb6 узнать, на каком пункте меню находится курсор.
Для примера, возьмём меню "файл".
Caption | Name
Файл | MnuFile
Создать | MnuFileNew
Открыть | MnuFileOpen
Ну, и пожалуй, хватит. И так будет понятно.
Запускаем программу и жмём: либо f10, либо alt.
Затем стрелку вниз.
Меню "Создать", выделится другим цветом.
Так вот, как программно получить, где находится курсор?
Ведь, в vb нету свойства GotFocus у менюшек.
Очень надеюсь на вашу помощь!
---
С уважением: Иван Денишев.

Отвечает: Алексей Немиро // 17.02.2008 / 10:12

Здравствуйте, Иван.

ВНИМАНИЕ: Данный пример довольно опасный, и может привести к зависанию Visual Basic!

Скачать готовый пример можно тут: http://kbyte.ru/Code/Samples/form1.zip

Создайте новый EXE-проект, на форме разместите Timer и вставьте следующий код:

Код формы:
001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
Option Explicit

Private Sub Form_Load()
 gHW = Me.hwnd
 Hook
End Sub

Private Sub Form_Unload(Cancel As Integer)
 Unhook
End Sub

Private Sub Timer1_Timer()
 Me.Caption = SelectedMenuString
End Sub


Также добавьте несколько элементов меню.
Дополнительно создайте новый модуль и вставьте следующий код:

Код модуля:
001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
015:
016:
017:
018:
019:
020:
021:
022:
023:
024:
025:
026:
027:
028:
029:
030:
031:
032:
033:
034:
035:
036:
037:
038:
039:
040:
041:
042:
043:
044:
045:
046:
047:
048:
049:
050:
051:
052:
053:
054:
055:
056:
057:
058:
059:
060:
061:
062:
063:
064:
065:
066:
067:
068:
069:
070:
071:
072:
073:
074:
075:
076:
077:
078:
079:
080:
081:
082:
083:
084:
085:
086:
087:
088:
089:
090:
091:
092:
093:
094:
095:
096:
097:
098:
099:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
Option Explicit

Public SelectedMenuString As String 'здесь будет заголовок выбранного элемента меню

Private Declare Function CallWindowProc Lib "user32" _
  Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
  ByVal hwnd As Long, ByVal Msg As Long, _
  ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function SetWindowLong Lib "user32" _
  Alias "SetWindowLongA" (ByVal hwnd As Long, _
  ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function GetMenu Lib "user32" _
 (ByVal hwnd As Long) As Long

Private Declare Function GetSubMenu Lib "user32" _
 (ByVal hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function GetMenuItemCount Lib "user32" _
 (ByVal hMenu As Long) As Long

Private Declare Function GetMenuState Lib "user32" _
 (ByVal hMenu As Long, ByVal wID As Long, _
  ByVal wFlags As Long) As Long

Private Declare Function GetMenuString Lib "user32" _
  Alias "GetMenuStringA" (ByVal hMenu As Long, _
  ByVal wIDItem As Long, ByVal lpString As String, _
  ByVal nMaxCount As Long, ByVal wFlag As Long) As Long

Private Const MF_BYPOSITION = &H400&
Private Const MF_HILITE = &H80&
Private Const WM_MENUSELECT = &H11F
Private Const GWL_WNDPROC = -4

Public lpPrevWndProc As Long
Public gHW As Long

Public Sub Hook()
  'Begin hooking into messages.
  lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
  AddressOf WindowProc)
End Sub

Public Sub Unhook()
  'Cease hooking into messages.
  SetWindowLong gHW, GWL_WNDPROC, lpPrevWndProc
End Sub

Function AnyLit(hSubSubMenu As Long) As Long
  Dim i As Long
  Dim MenuCount As Long

  'Get the number of items in the menu.
  MenuCount = GetMenuItemCount(hSubSubMenu)

  'Loop through the menu items.
  For i = 0 To MenuCount - 1
    'Check whether this item is highlighted.
    If GetMenuState(hSubSubMenu, i, MF_BYPOSITION) And _
        MF_HILITE Then
      AnyLit = True
      Exit Function
    End If
  Next i

  'Return FALSE, no items highlighted.
  AnyLit = False
End Function

Private Sub WalkSubMenu(hSubMenu As Long)
  Dim i As Long
  Dim MenuItems As Long
  Dim hSubSubMenu As Long
  Dim buffer As String
  Dim result As Long

  'Get the count of menu items in this menu.
  MenuItems = GetMenuItemCount(hSubMenu)

  'Loop through all the items on the menu.
  For i = 0 To MenuItems - 1
    'Determine whether this item is highlighted.
    If GetMenuState(hSubMenu, i, MF_BYPOSITION) And _
        MF_HILITE Then
      'Attempt to get a submenu for each menu item.
      hSubSubMenu = GetSubMenu(hSubMenu, i)

      'Check for a submenu with something selected on it.
      If hSubSubMenu And AnyLit(hSubSubMenu) Then
        'There is a submenu with a selection so walk it.
        WalkSubMenu hSubSubMenu
      Else
        buffer = Space(255)
        result = GetMenuString(hSubMenu, i, buffer, Len(buffer), MF_BYPOSITION)
        buffer = Left$(buffer, result)
        SelectedMenuString = GetDescription(buffer)
        Exit Sub
      End If
    End If
  Next i
End Sub

Public Sub FindHilite(TheForm As Form)
  Dim hMenu As Long
  Dim hSubMenu As Long
  Dim i As Long
  Dim MenuCount As Long

  'Clear any previous description.
  SelectedMenuString = ""

  'Get the menu handle.
  hMenu = GetMenu(TheForm.hwnd)

  'Check to see if there is no menu.
  If hMenu <> 0 Then
    'Get the number of top-level menus.
    MenuCount = GetMenuItemCount(hMenu)

    'Enumerate through all top-level menus.
    For i = 0 To MenuCount - 1
      'Ignore top-level menus not currently selected.
      If GetMenuState(hMenu, i, MF_BYPOSITION) And _
          MF_HILITE Then
        'Get a handle to the submenu.
        hSubMenu = GetSubMenu(hMenu, i)

        'Walk the submenu.
        WalkSubMenu hSubMenu
      End If
    Next i
  End If
End Sub

Private Function GetDescription(MenuCaption As String) As String
 GetDescription = MenuCaption
End Function

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 If uMsg = WM_MENUSELECT Then
  FindHilite Form1
 End If
 WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function


При выборе элемента меню в переменной SelectedMenuString будет текст заголовка выбранного элемента меню.

 

Вопрос #000754: HttpWebRequest и HttpWebResponse

Автор вопроса: Сергей // 13.02.2008 / 23:01

Здравствуйте.
Алексей Сергеевич в статье "Взаимодействие с другими сайтами через HTTP" хорошо описал, как можно программно заполнить и отправить Web-форму и получить результат. Спасибо. А как быть, если есть защита от автоматов? Т.е. как отобразить имиджи с цифрами, получить и отправить выбранный вручную ответ? Спасибо.

--------------------------------------
Категория: --- C# (Си шарп)

Отвечает: Алексей Немиро // 14.02.2008 / 03:35

Здравствуйте, Сергей.

Для этого придется икать уязвимости в самой CAPTCHA, «проще всего» разобраться с картинкой, которая в url содержит код, по которому она была сгенерирована.

http://www.captcha.ru/breakings/

Также можно попробовать написать распозновалку картинок, но это уже зависит от ее кривизны и окраски, чем меньше кривизны и меньше цветов, тем больше вероятность написать нормальную распозновалку.

Либо придется подключать человека, отдавать ему картинки и чтобы он сам вручную вводил номера.


--
С наилучшими пожеланиями,
Немиро Алексей http://aleksey.nemiro.ru/

 

Вопрос #000745: Проблема с компонентом WINSOCK

Автор вопроса: Дмитрий // 10.02.2008 / 15:57

Уважаемые Эксперты!
Помогите решить вот такую проблему: создал приложение с использованием сокетов но на других компьютерах оно не запускается из-за того что якобы отсутствует компонент MSWINSCK.OCX. Как можно решить эту проблему?
Заранее спасибо


--------------------------------------
Категория: --- Visual Basic 5.0/6.0

Отвечает: Алексей Немиро // 10.02.2008 / 16:09

Здравствуйте, Дмитрий!

Файл MSWINSCK.OCX можно найти в папке WINDOWS\system32 Вашего
компьютера. Чтобы Ваша программа работала на другом компьютере, Вам
необходимо перенести этот файл, и возможно зарегистрировать его.
Регистрация компонентов производится программой regsvr32.exe,
которую можно найти в той же папке (system32). Для регистрации достаточно
перетащить файл компонента (mswinsck.ocx) на файл regsvr32.exe в проводнике Windows.


--
С наилучшими пожеланиями,
Немиро Алексей http://aleksey.nemiro.ru/

 

Вопрос #000743: C#, forms

Автор вопроса: "Slonov K." // 09.02.2008 / 14:05



Добрый день.
C# .
Есть форма(Form1) с кнопкой, при нажатии на неё создаётся другая
форма(Form2).

private void button1_Click(object sender, EventArgs e)
{
Form2 Fr = new Form2();
Fr.Show();
}

Вопрос : как добиться чтобы чтобы при повторном нажатии на эту же
кнопку не создавалось ещё одно окно(типа Form2) , а просто
становилось становилось активным уже существующее Fr.
Заранее спасибо.
Костя

З.Ы. Может я что то принципиально не так делаю?

Отвечает: EROS // 10.02.2008 / 18:36

Здравствуйте
Подобного поведения можно добиться различными способами, вот один из
них:

001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
private void button1_Click(object sender, EventArgs e)
    {
      foreach (Form item in Application.OpenForms)
      {
        if (item is Form2)
        {
          item.Focus();
          return;
        }
      }

      Form2 frm = new Form2();
      frm.Show();
    }


--
С уважением,
EROS mailto:eros@fromru.com

 

Вопрос #000735: Localization and DataBase

Автор вопроса: Taleh Mikailov // 05.02.2008 / 15:36

Здравствуйте уважаемые эксперты!
На свой вопрос, что написал прошлый раз не получил ответа. В связи с этим решил более подробнее обьяснить ситуацию и более точно сформулировать свой вопрос...
Мне нужно включить в Веб Приложение поддержку локализации из Баз Данных.
Долго искал, по этому вопросу, какой-нибудь материал в сети.
Мое внимание привлекла вот эта статья: www.microsoft.com/rus/msdn/publish/articles/asap.mspx
После того, как прочитал статью, для примера создал не большое приложение и одну таблицу в Базе Данных()
Таблица(StringResources) из Базы Данных(CustomResourceProviderSample)

resourceType | cultureCode |resourceKey | resourceValue
Default.aspx en lbHelloLocalResource1.Text Hello(en)
Default.aspx en lbLanguageLocalResource1.Text English(en)
Default.aspx en lbWelcomeLocalResource1.Text Welcome(en)
Default.aspx en hlAboutCompanyLocalResource1.Text About Company(en)
Default.aspx en hlContactUsLocalResource1.Text Contact Us(en)
Default.aspx en hlLearnMoreLocalResource1.Text Learn More(en)
Default.aspx en btnSendDemoMailLocalResource1.Text Send Demo Mail(en)
AboutCompany.aspx en lbCompanyNameLocalResource1.Text MatrixSoftware(en)
AboutCompany.aspx en Literal1LocalResource1.Text "Текст с описанием фирмы(en)"
AboutCompany.aspx en hlContactUsLocalResource1.Text Contact Us(en)
AboutCompany.aspx en btnBackLocalResource1.Text Main Page(en)


Обращение к ресурсам осуществляю следующим образом:

this.lbHello.Text = HttpContext.GetLocalResourceObject("Default.aspx", "lbHelloLocalResource1.Text") as string;

Одним словом строго следую указаниям из статьи...
Проблема в том, что при компиляции приложения получаю 8 ошибок:

Error 1 The type or namespace name 'ResourceProviderFactory' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProviderFactory.cs 11 46 CustomResourceProviders


using System;

using System.Web;

using System.Diagnostics;

using System.Globalization;

using System.Resources;

using System.Threading;

namespace CustomResourceProviders

{

public class DBResourceProviderFactory : ResourceProviderFactory

{

public override IResourceProvider CreateGlobalResourceProvider(string classKey)

{

Debug.WriteLine(String.Format(CultureInfo.InvariantCulture, "DBResourceProviderFactory.CreateGlobalResourceProvider({0})", classKey));

return new DBResourceProvider(classKey);

}

public override IResourceProvider CreateLocalResourceProvider(string virtualPath)

{

Debug.WriteLine(String.Format(CultureInfo.InvariantCulture, "DBResourceProviderFactory.CreateLocalResourceProvider({0}", virtualPath));

// we should always get a path from the runtime

string classKey = virtualPath;

if (!string.IsNullOrEmpty(virtualPath))

{

virtualPath = virtualPath.Remove(0, 1);

classKey = virtualPath.Remove(0, virtualPath.IndexOf('/') + 1);

}

return new DBResourceProvider(classKey);

}

}

}

-----------------------------------

Error 2 The type or namespace name 'Compilation' does not exist in the namespace 'System.Web' (are you missing an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProvider.cs 2 18 CustomResourceProviders


using System.Web.Compilation; <-????

------------------------------------------

Error 3 The type or namespace name 'DisposableBaseType' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProvider.cs 17 36 CustomResourceProviders


namespace CustomResourceProviders

{

/// <summary>

/// Resource provider accessing resources from the database.

/// This type is thread safe.

/// </summary>

public class DBResourceProvider : DisposableBaseType, IResourceProvider <- ????????

{

private string m_classKey;

private StringResourcesDALC m_dalc;

// resource cache

private Dictionary<string, Dictionary<string, string>> m_resourceCache = new Dictionary<string, Dictionary<string, string>>();

/// <summary>

/// Constructs this instance of the provider

/// supplying a resource type for the instance.

/// </summary>

--------------------------------------------

Error 4 The type or namespace name 'IResourceProvider' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProvider.cs 17 56 CustomResourceProviders


------------------------------------

Error 5 The type or namespace name 'Security' does not exist in the namespace 'System.Web' (are you missing an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceReader.cs 5 18 CustomResourceProviders
С этой разобрался!

Error 6 The type or namespace name 'DisposableBaseType' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceReader.cs 23 34 CustomResourceProviders


Error 7 The type or namespace name 'IResourceProvider' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProviderFactory.cs 14 25 CustomResourceProviders


Error 8 The type or namespace name 'IResourceProvider' could not be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\talekh\My Documents\Visual Studio 2005\Projects\DBResourceProviderWeb\CustomResourceProviders\DBResourceProviderFactory.cs 20 25 CustomResourceProviders


Совсем НЕ уверен, что делаю все как надобно, поэтому обращаюсь к вам !!!
Очень прошу помочь !!!

Буду рад получить от вас замечания и исправления !!!
Заранее благодарю!!!

Отвечает: EROS // 08.02.2008 / 03:47

Здравствуйте.
Судя по описанию ошибок вы не подключили необходимые библиотеки либо
не указали нужную директиву using


--
С уважением,
EROS

 


Чтобы задать Ваш вопрос, отправьте его на адрес expert@kbyte.ru

Раздел Эксперт на сайте Kbyte.Ru

Наверх

 

 

Последнее на форумах

создать PictureBox | Автор: Vetolez
Добавлено: 23.02.2008 / 16:55 | ответов: 5 | просмотров: 92

Возник у меня такой вопрос. Сам не могу решить, пробовал неоднократно.
Задача такая, мне нужно создавать PictureBox уже после запуска программы, не в режиме написания и создания программы.
Заранее спасибо!

Ответить на это сообщение | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 1 | Автор: Артeм
Добавлено:23.02.2008 / 19:27
001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
Dim myPicBox As New PictureBox

 With myPicBox
.Width = 100
.Height = 100
.left=100
.Top=100
End With

Me.Controls.Add(myPicBox)

Colorized by: Eros.CodeSyntaxColor Engine

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 2 | Автор: Артeм
Добавлено:23.02.2008 / 19:48
Кстати это для любого контролла... т.е. тип Control

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 3 | Автор: 5acred Phoenix
Добавлено:23.02.2008 / 20:56
Аффтар хочет VB6, сюдя по подфоруму

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 4 | Автор: Артeм
Добавлено:23.02.2008 / 21:07
На VB6 то же самое почти... (я на память пишу...)

001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
Dim myPicBox As Picture

Set myPicBox = New Picture

With myPicBox
.Width = 100
.Height = 100
.left=100
.Top=100
End With

Form1.Controls.Add(myPicBox)

Colorized by: Eros.CodeSyntaxColor Engine

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 5 | Автор: 5acred Phoenix
Добавлено:23.02.2008 / 21:17
Просто я не помню, есть ли там свойство .Controls.

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Всех с 23 февраля! | Автор: Алексей
Добавлено: 23.02.2008 / 05:13 | ответов: 0 | просмотров: 11

сабж.

Ответить на это сообщение | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ошибка сохранения в базу | Автор: BigDan
Добавлено: 22.02.2008 / 14:03 | ответов: 4 | просмотров: 81

Всем доброго времени суток! не могу понять чего он от меня хочет)))! вот ошибка

Тип ошибки:
Microsoft JET Database Engine (0x80040E09)
Обновление невозможно. База данных или объект доступны только для чтения.
/euzm/cpanel/edit_home_page.asp, line 29

вот код

if Len(request.form("elm1")) >= 1 then
Set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM home"
rs.Open strSQL, Conn, 2,2

rs("description") = request("elm1")

rs.update
rs.close

response.Write("<script type='text/javascript'> window.opener.location.href = window.opener.location.href; </script>")
response.Write("<script type=text/javascript> window.close(); </script>")

end if



Ответить на это сообщение | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 1 | Автор: Алексей
Добавлено:22.02.2008 / 14:11
Может у файла базы действительно атрибут ReadOnly стоит?
или она просто открыта чем-то другим..

_________________
Это сообщение добавлено через Kbyte.Ru Forum Mail Conference (FMC)

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 2 | Автор: BigDan
Добавлено:22.02.2008 / 17:29
Та нет Алексей я проверил базу там все ок атрибут не стоит, все закрыто я думаю может мне нужно локальный сервер настроить правильно я если честно в этом полный профан если можешь то объясни плиз мне бестолковому как его правильно настроить, я использую стандартный виндовский сервак для работы с асп, может там че нужно проставить или указать, ПОМОГИТЕ ПЛИЗ, ну так же не бывает?????

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 3 | Автор: Алексей
Добавлено:23.02.2008 / 04:20
Попробуй права у файла и директории на запись поставить, в IIS тоже.

deja vu :-)

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 4 | Автор: Артeм
Добавлено:23.02.2008 / 19:58
Попробуй для теста, чтобы определить не с правами ли проблема установить в IIS запуск приложений и ASP от имени админа... с его паролем...

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


ASP.NET работа за кадром | Автор: ave_maria
Добавлено: 20.02.2008 / 21:58 | ответов: 3 | просмотров: 101

Zdrasti :) iy nadeus' menia ne zakidaut pomodorami esli iy sproshy
dostatochno premetivniy vopros no dymau ne luboi programmist smojet otvetit'

dopystim aplikazia napisannaia na ASP.NET (daje ne ochen' vajno kakaia versia :) )
iy kompiliryu kod, zapuskaiu, a vot s etogo momenta esli mojno popodrobnee chto i kak proishodit ,
i esli mojno po ocherdnost'.

ili dopystim na forme est' mnogo vsiakih controls i naprimer button pri najatii kotorogo proishodit event etogo buttona
a do etogo momenta kak vse rabotaet? esli y kogo est' interesnie stat'i pochitat' bila bi ochen' priznatel'na
Spasibo masha

Ответить на это сообщение | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 1 | Автор: Алексей
Добавлено:21.02.2008 / 08:23
Подобную информацию обычно пишут во всех книжках по программированию на ASP .NET.

wiki :
Хотя ASP.NET берёт своё название от старой технологии Microsoft ASP, она значительно от нее отличается. Microsoft полностью перестроила ASP.NET, основываясь на Common Language Runtime (CLR), который является основой всех приложений Microsoft .NET. Разработчики могут писать код для ASP.NET, используя практически любые языки программирования, в том числе, и входящие в комплект .NET Framework(C#, Visual Basic.NET, и JScript .NET). ASP.NET имеет преимущество в скорости по сравнению с скриптовыми технологиями, так как при первом обращении код компилируется и помещается в специальный кеш, и впоследствии только исполняется, не требуя затрат времени на парсинг, оптимизацию, и т. д.

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 2 | Автор: Алексей
Добавлено:21.02.2008 / 08:27

Внутри ASP.NET

Автор: Mika Soukhov
The RSDN Group

Источник: RSDN Magazine #6-2003
Опубликовано: 07.08.2004
Исправлено: 05.03.2006
Версия текста: 1.0
Вступление
От неуправляемого к управляемому. От IIS к ASP.NET
HTTP-конвейеры
Заключение
<script language="javascript"> function ToggleCode(id) { el=document.getElementById(id); img=document.getElementById("img"+id); if(el.style.display=="none") { img.src="http://www.rsdn.ru/images/ls2.gif"; el.style.display=""; } else { img.src="http://www.rsdn.ru/images/ls1.gif"; el.style.display="none"; } return false; } </script>

Вступление

Что такое ASP.NET? Одни скажут, что это среда для разработки крупных порталов, другие – средство для быстрого создания Web-сервисов. Для третьих ASP.NET – это инструмент разработки сайтов, адаптированных для работы на мобильных устройствах. И все они окажутся правы.

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

От неуправляемого к управляемому. От IIS к ASP.NET

ISAPI расширения

Во всех новых версиях Windows (XP, 2000 и 2003) есть компонент Internet Information Services (IIS). Получив запрос, IIS “смотрит”, к какому типу этот запрос относится (*.asp, *.shtml или *.aspx). Если IIS не способен самостоятельно обработать запрос (например, *.html или *.htm он может обрабатывать самостоятельно), то он передает его соответствующему ISAPI-расширению. Чтобы увидеть все доступные расширения, нужно:

  • запустить оснастку IIS Manager;
  • в контекстном меню узла Web Sites выбрать пункт меню “Properties”;
  • в появившемся окне свойств выбрать закладку “Home Directory”;
  • в группе “Application Settings” нажать кнопку “Configurations…”;
  • перейти на закладку “Mappings”.

В списке “Application Extensions” (в этой статье приводятся названия, используемые в Windows Server 2003) будут указаны все ISAPI-расширения IIS, установленные на текущий момент. Среди них наверняка будет и aspnet_isapi.dll (предполагается, что на компьютере читателя установлен IIS, а после него – .NET Framework, при другой последовательности установки ISAPI-расширение не будет зарегистрировано).

ПРИМЕЧАНИЕ

Иногда необходимо вручную зарегистрировать ASP.NET в IIS, к примеру, IIS установлен позднее .NET Framework, или, скажем, после обновления .NET Framework IIS не “увидел” изменений. Самый простой способ решить эту проблему – воспользоваться утилитой aspnet_regiis.exe. Она сможет самостоятельно зарегистрировать расширение aspnet_isapi.dll и сконфигурировать IIS.

Так что же это за расширение?

ASP.NET Hosting Runtime

Это – ISAPI-расширение (aspnet_isapi.dll), и предназначено оно для получения запросов, адресованных ASP.NET-приложениям (*.aspx *.asmx и т.д.), а также создания рабочих процессов aspnet_wp.exe, обратывающих запросы (aspnet_wp.exe – процесс, в котором, собственно, и работает ASP.NET, в Windows 2003 этот процесс носит более звучное имя – w3wp.exe).

Получив такой запрос, расширение проверяет настройки в секции <processModel> конфигурационного файла machine.config, находящегося в каталоге “%SystemRoot%\Microsoft.NET\Framework\v%CLRVersion%\CONFIG. Если уже существующий процесс aspnet_wp.exe не удовлетворяет хотя бы одному требованию, указанному в настройках, то aspnet_isapi.dll создает новый процесс с “правильными” настройками. При этом старый рабочий процесс продолжает существовать до окончания обработки выполняемых запросов, после чего удаляется.

ПРИМЕЧАНИЕ

В ASP.NET появилась модель рабочих процессов «Web Garden», которая позволяет на мультипроцессорных серверах создавать несколько экземпляров рабочих процессов. Чтобы разрешить поддержку этой модели, нужно установить атрибут webGarden секции <processModel> в true. При этом также рекомендуется задать значение атрибута cpuMask. Это битовая маска, значение которой задается в шестнадцатеричном формате. Маска указывает, какие из доступных процессоров будут участвовать в работе. Например, если маска установлена в 0x0D (в двоичном виде – 1101), то процессор номер 1 (нумерация идет справа и начинается с нуля) не будет участвовать в работе. Если webGarden установлен в false, то значение cpuMask игнорируется. Следует отметить, что Windows 2003 позволяет создавать несколько экземпляров w3wp.exe и для однопроцессорной машины.

При создании этого процесса через командную строку ему можно передать следующие параметры:

ПараметрОписание
IIS-Process-IDИдентификатор процесса IIS.
This-Process-Unique-IDИдентификатор процесса, использующийся при включенном режиме «Web Garden».
Number-of-Sync-PipesЧисло каналов (pipes), по которым может поступать информация.
RPC_C_AUTHN_LEVEL_XXXУровень аутентификации для модели безопасности COM, по умолчанию - CONNECT.
RPC_C_IMP_LEVEL_XXXУровень имперсонации для модели безопасности COM, по умолчанию - IMPERSONATE.
CPU-MaskБитовая маска доступных процессоров.
Max-Worker-ThreadsМаксимальное число рабочих потоков в пуле на каждый процессор.
Max-IO-ThreadsМаксимальное число I/O потоков в пуле на каждый процессор.
Таблица 1

Aspnet_isapi.dll общается с процессом aspnet_wp.exe через асинхронные именованные каналы (pipes). Через них aspnet_isapi.dll производит мониторинг рабочего процесса. Параметры сервера, получаемые как значение свойства HttpRequest.ServerVariables, также передаются через эти каналы. Имена каналов формируются автоматически, при их формировании используются количество каналов (Number-of-Sync-Pipes) и идентификатор процесса (IIS-Process-ID).

ПРИМЕЧАНИЕ

При использовании модели «Web Garden» в работе принимает участие параметр This-Process-Unique-ID. Но тут есть один нюанс. Дело в том, что aspnet_isapi.dll не знает, какой ID будет у процесса aspnet_wp.exe, так как данная информация становится известна только после создания этого процесса (она возвращается в параметре lpProcessInformation функции CreateProcess). Поэтому вместо идентификатора передается только что сгенерированный GUID.

В поставку ASP.NET входит aspnet_filter.dll. Этот фильтр предназначен для работы с “cookieless”-сессиями. В таких сессиях их идентификаторы передаются не в теле сообщения (http-заголовок “Cookie”), а в конце URL. Существование таких сессий обусловлено тем, что некоторые HTTP-клиенты в целях безопасности не работают с Cookie-файлами. Фильтр aspnet_filter.dll получает и разбирает строку запроса, после чего дописывает идентификатор сессии в тело сообщения под новым http-заголовком “AspFilterSessionId”.

Aspnet_state.exe – это сервис, предназначенный для хранения состояния сессий ASP.NET. Чтобы сохранять состояние сессии с помощью этого сервиса, нужно установить в конфигурационном файле значение атрибута mode секции <sessionState> в значение StateServer. Сохранение данных сессии в отдельном процессе обеспечивает большую надежность системы. Это позволяет не заботиться о процессе сбора мусора (не путать со сборкой мусора в .NET), который проводит aspnet_isapi.dll. Ведь aspnet_isapi.dll может с легкостью удалить процесс aspnet_wp.exe, в котором находятся все ваши приложения и их данные. Это может произойти по ряду причин, таких как: истечение времени ожидания ответа от aspnet_wp.exe, превышение порогового значения объёма используемой памяти и т.п.

Если предполагаются длительные и ресурсоемкие операции на сервере, то желательно увеличить некоторые значения, находящиеся в секции <processModel> файла machine.config, чтобы aspnet_isapi.dll не удалила по ошибке исправно работающее приложение. Стоит заметить, что значения по умолчанию, выставленные в этой секции, в большинстве случаев оказываются оптимальными. Поэтому, если возникает необходимость изменения пороговых значений, самое время задуматься о рефакторинге приложения.


Рисунок 1. Процесс активации ASP.NET-среды IIS-ом.

ПРИМЕЧАНИЕ

В Windows Server 2003 слушающий сокет (HTTP Listener), ранее интегрированный в IIS, реализован на уровне ядра (см. рисунок 1, модуль HTTP.SYS). Получая запросы, он не сразу передает их сервису, а сначала проверяет расширение запроса. Этим занимается модуль Web Administration Service (WAS). Если запрос предназначается ASP.NET-приложению, WAS создает рабочий процес w3wp.exe и передает в него запрос, в ином случае – в IIS. Благодаря этому обработка данных происходит значительно быстрее, нежели это происходило бы при лишнем обращении через границы процесса IIS.

Интересный факт – можно выставить для IIS 6.0 уровень изоляции, при котором ASP.NET будет работать через IIS. Для этого нужно:

  • запустить оснастку IIS Manager;
  • в контекстном меню узла Web Sites выбрать пункт меню “Properties”;
  • в появившемся окне свойств выбрать закладку “Service”;
  • установить флаг “Run WWW service in IIS 5.0 isolation mode” во включенное состояние.

Теперь данные, находящиеся в секции <processModel> файла machine.config, не будут учитываться, и настройки нужно будет производить только через оснастку IIS Manager. Для этого в контекстном меню секции Application Pool нужно выбрать пункт меню “Properties”. В появившемся окне свойств можно увидеть настройки, в том числе и те, которые выставляются в <processModel>.

HTTP-конвейеры

Инициализация HttpApplication

Хостинг ASP.NET

Что же представляет собою aspnet_wp.exe? Это unmanaged-приложение, являющееся хостом CLR. aspnet_wp.exe активирует CLR через CorBindToRuntimeEx, после чего создается домен для CLR. Далее происходит процесс инициализации среды ASP.NET. Для этого создается еще один отдельный домен с помощью метода ApplicationHost.CreateApplicationHost. В него передается тип класса, через который будет происходить процесс передачи и получения данных из обычного .NET-приложения в среду ASP.NET. В данном случае это класс ISAPIRuntime. Так же при создании домена передаются физический и виртуальный пути к ASP.NET-приложению.

Новый домен будет создан при первом обращении к какому-нибудь виртуальному пути. Количество создаваемых доменов не ограничено ничем, кроме объёма доступной памяти. Это настраивается в атрибуте memoryLimit секции <processModel>, и по умолчанию равно 60% от общего объема памяти.

При создании домена для ASP.NET среды проверяются настройки из файла machine.config. Значения настроек выбираются и из локального файла конфигурации web.config, который находится в папке приложения. Если одинаковые настройки встретились в обоих файлах, то, как правило, используются настройки из файла web.config.

Настройки из web.config могут заместить многие, хотя и не все, настройки из machine.config. Так, например, значения из секции <processModel>, используются в процессе создания нового рабочего процесса, который, в свою очередь, создает домен, конфигурируемый файлом web.config. Другими словами, домен с конкретным конфигурационным файлом web.config будет создан много позже считывания значений из <processModel> конфигурационного файла machine.config. Поэтому значения секции <processModel>, записанные в файле web.config, будут проигнорированы.

Некоторые настройки создаются путем объединения всех конфигурационных файлов, лежащих в виртуальных папках, которые сервер находит, просматривая виртуальный путь, к которому осуществляется запрос. Соответственно, machine.config – конфигурирующий файл корневого каталога всех виртуальных папок. Поэтому все, что можно разрешить на верхнем уровне, можно запретить на нижнем. Например, мое приложение называется MyWebApp. В его директории есть вложенная папка с названием MyWebAppSecurity. В обеих папках лежат файлы web.config. И если теперь разрешить всем пользователям обращаться анонимно к файлам каталога MyWebApp, то для MyWebApp/MyWebAppSecurity это можно запретить. Настройки авторизации прописываются в секции <authorization>.

После создания домена вызыватся метод ISAPIRuntime.ProcessRequest. Внутри этого метода (мы уже находимся в домене запрашиваемого ASP.NET-приложения) создается объект, класс которого является наследником HttpWorkerRequest. Этот объект передается в метод HttpRuntime.ProcessRequest. На данный момент существуют три класса, реализующие HttpWorkerRequest и используемые ISAPIRuntime.

КлассОписание
ISAPIWorkerRequestOutOfProcASP.NET работает с IIS 5.0
ISAPIWorkerRequestInProcForIIS6ASP.NET работает через IIS 6.0 (под Windows 2003)
ISAPIWorkerRequestInProcASP.NET работает без IIS 6.0 (под Windows 2003)
Таблица 2. Классы, реализующие HttpWorkerRequest

Вот отсюда, по большому счету, и начинается ASP.NET. Давайте разберем поподробнее, что именно происходит в недрах HttpRuntime. Для этого я привел UML-диаграмму последовательности вызовов для более наглядного представления происходящего внутри классов из пространства имен System.Web.


Рисунок 2. Процесс активации и инициализации объекта HttpApplication.

При первом вызове статического метода HttpRuntime.ProcessRequest производится инициализация очередей запросов, мониторинга состояния домена, создания профайлера (Profiler) для вывода трассировочной информации, настройки которого хранятся в секции <trace> и т.д. Также в этот момент производится загрузка всех сборок с расширением dll, находящихся в папке bin. После этого HttpRuntime подписывается на событие выгрузки домена, в обработчике которого будет вызван метод Application_End. Домен может быть выгружен в нескольких случаях. Первый – это когда произошла ошибка на ранних этапах инициализации HttpRuntime или при завершении обработки запроса. Второй – если произошли изменения в конфигурационных файлах (web.config, machine.config или файлы конфигурации, устанавливающие уровни политики безопасности в секции <trustLevel>). Третий – когда была удалена или переименована директория bin. И, наконец, четвертый – принудительно был вызван метод HttpRuntime.UnloadAppDomain.

Закончив процесс инициализации, HttpRuntime создает обработчик события, извещающего об окончании отсылки ответа, и передает его клиентской программе через вызов метода HttpWorkerRequest.SetEndOfSendNotification. В этом обработчике производится освобождение ресурсов, занятых объектами HttpRequest и HttpResponse. Так что программистам, работающим с HttpWorkerRequest, настоятельно рекомендуется вызывать этот метод, чтобы предотвратить утечку ресурсов.

HttpRuntime создает экземпляр HttpContext, который, в свою очередь, инициализирует HttpRequest и HttpResponse. Затем через фабрику HttpApplicationFactory создается новый экземпляр HttpApplication. В него загружается его состояние, то есть объект класса HttpApplicationState. После этого происходит процесс инициализации созданного экземпляра HttpApplication.

Так для чего нужен HttpApplication? Фактически этот объект является олицетворением всех ASP.NET-сущностей, таких, как: Web-страница (*.aspx), User control (*.ascx), Web-сервис (*.asmx) или HTTP-обработчик (*.ashx). При обращении к ним создается отдельный экземпляр HttpApplication. Все события, вся обработка информации происходят в нем, и все методы конечного объекта (Page, WebService и т.д.) вызываются прямо или косвенно из этого класса. Иными словами, HttpApplication – это мозг всего ASP.NET.

Парсинг и компиляция ASP.NET-файлов

При первом вызове метода HttpApplicationFactory.GetApplicationInstance происходит процесс парсинга и компиляции ASP.NET-файлов проекта. Основную работу выполняет класс BuildManager из пространства имен System.Web.Compilation.


Рисунок 3. Процесс парсинга и компиляции ASP.NET-файлов.

Экземпляр HttpApplication вызывает статический метод BuildManager.GetGlobalAsaxType. В этом методе проверяется, нужна ли перекомпиляция. Чтобы разобраться, как среда ASP.NET решает, нужна ли перекомпиляция сборок, давайте зайдем в каталог “%SystemRoot%\Microsoft.NET\Framework\v%CLRVersion%\Temporary ASP.NET Files”. Здесь находятся подкаталоги с названиями Web-приложений. Вот примерная структура дерева каталогов, которую можно увидеть, зайдя в любую папку ASP.NET-приложения:

\Microsoft .NET  \Framework   \v%CLRVersion%    \Temporary ASP.NET Files     \WebService      \a45ede38      
\336d7fb3 

Имена двух последних уровней являются текстовым представлением хеш-значений всех сборок, содержащих код приложения.

ПРИМЕЧАНИЕ

Временная папка “Temporary ASP.NET Files” может и не находиться в каталоге “%SystemRoot%\. Чтобы изменить путь к временным файлам ASP.NET-приложений, нужно изменить в реестре значение ключа Path (в HTLM\Software\Microsoft\ASP.NET\v%CLRVersion%\).

В таких папках находятся XML-файлы вида [filename].[hashcode].compiled следующего содержания:

<preserve resultType="2" assembly="Code"  hash="a433b8acd5ef24" usesExistingAssembly="true" type="Service_asmx">  <filedep name="/WebService/Service.asmx"/> </preserve>

Именно по хеш-значениям ASP.NET определяет, изменился ли файл, и требуется ли перекомпиляция.

Если необходима перекомпиляция, то BuildManaged создает экземпляр класса BuildProviderHost и передает ему коллекцию объектов, реализующих IBuildProvider. Список классов этих объектов регистрируется в секции <buildProviders>. Провайдеры классифицируются по расширению обрабатываемых ими файлов. Эти расширения определяются значением атрибута extension в секции <buildProviders>. После этого экземпляр класса BuildProviderHost выбирает нужный IBuildProvider и вызывает его метод GenerateCode, передавая в него ссылку на самого себя. С помощью IBuildProvider создается экземпляр производного класса BaseParser, который занимается парсингом *.as*x-файлов.

После окончания парсинга класс, реализующий IBuildProvider, вызывает методы класса BuildProviderHost, осуществляющие компиляцию. Этим методам передаются результаты работы парсера и другие данные, которые могут потребоваться позже. Это могут быть название файла, название типа и т.д. Какой именно компилятор нужно использовать, задается в секции <compilers>.

ПРИМЕЧАНИЕ

Каждый домен позволяет перекомпилировать себя определенное количество раз. Этот предел задается в секции <compilation> атрибутом numRecompilesBeforeAppRestart. По умолчанию он равен 15. При этом происходит выгрузка всего домена, так как CLR позволяет выгружать только домены, а не отдельные сборки.

Global.asax

После разбора и компиляции файла фабрика классов HttpApplicationFactory получила описание класса (ссылку на объект System.Type), производного от HttpApplication, и начинает искать в нем с помощью технологии “отражения” (reflection) специальные методы Application_OnStart, Application_OnEnd, Session_OnStart, Session_OnEnd (или эквивалентные им Application_Start, Application_End, Session_Start, Session_End). Они будут вызываться самой фабрикой HttpApplicationFactory. Затем производится поиск оставшихся методов вида Application_Error, Application_BeginRequest, Application_EndRequest и их привязка к событиям объекта HttpApplication.

Заметьте, что класс Global из файла global.asax не содержит явной подписки на события. Эта подписка производится неявно. Не зная этого, можно произвести подписку вручную, а потом удивляться тому, что события приходят дважды. Что ж, еще одним секретом меньше в нашем мире.

ПРИМЕЧАНИЕ

Если вы хотите «привязать» вручную класс Global к соответствующим событиям, не пользуясь при этом дизайнером Visual Studio, нужно давать имена методам, обрабатывающим события, в соответствии со следующим шаблоном: Application_[On]%EventName%.

Пару слов о событии Application_Error. Если в момент обработки произошло исключение, то оно передается в метод HttpContext.AddError, где сохраняется до окончания обработки запроса. Для этого в HttpContext находится динамический список, где сохраняются объекты типа Exception. Чтобы получить все такие исключения, можно, вызвать свойство HttpContext.AllErrors.

Создав экземпляр HttpApplication, фабрика HttpApplicationFactory вызывает событие Application_Start, что сигнализирует о начале работы приложения.

Http-модули

После запуска приложения происходит инициализация созданного экземпляра класса HttpApplication. В начале создаются Http-модули (классы, реализующие интерфейс IHttpModule), перечень которых находится в секции <httpModules>. В файле machine.config зарегистрированы такие модули, как OutputCacheModule, SessionStateModule, SessionIDModule, FormsAuthenticationModule и т.д. Наиболее интересным является модуль, отвечающий за состояние данных сессии. Без сессий не могло быть и речи о безопасности. Все известные типы аутентификаций (Form, Windows) основаны на механизме сессий. Созданием сессий и занимается модуль SessionStateModule.

SessionStateModule хранит свои настройки в секции <sessionState>. Атрибут mode этой секции указывает на то, как будет храниться сессия. Он может принимать одно из следующих значений:

ЗначениеОписание
OffСессия не поддерживается.
InProcХранить данные локально в памяти рабочего процесса.
StateServerХранить данные в процессе aspnet_state.exe.
SQLServerХранить данные в SQL-сервере.
CustomХранить данные в другом хранилище.

Соответственно, в .NET Framework есть классы, реализующие приведенные выше модели хранения. Это InProcSessionStateStore, OutOfProcSessionStateStore, SqlSessionStateStore. Но, как и многое другое, эти классы объявлены как private.

Чтобы реализовать собственное хранилище, нужно создать класс, реализующий интерфейс ISessionStateStore, а в атрибуте mode выставить значение Custom, а в дополнительном атрибуте type указать полное имя типа вашего класса.

SessionStateModule подписывается на три события HttpApplication: асинхронное событие изменения состояния сессии (AcquireRequestStateAsync), событие сохранения состояния сессии (ReleaseRequestState), событие окончания запроса (EndRequest).

В обработчике AcquireRequestStateAsync модуль сохраняет состояние сессии в экземпляр класса HttpContext. Для этого он создает экземпляр класса HttpSessionState и добавляет его со значением ключа “AspSession” в коллекцию HttpContext.Items. Но в программе для получения состояния сессии в целях удобства лучше использовать свойство HttpContext.Session. При создании сессии вызывается событие Session_Start.

В обработчике ReleaseRequestState проверяется, был ли вызван метод HttpSessionState.Abandon. Если да, то вызывается метод HttpApplication.EndSession (который передает управление в метод Global.Session_End).

ПРИМЕЧАНИЕ

Время жизни сессии по умолчанию равно 20 минутам. Это значение можно изменить, отредактировав значение атрибута timeout секции <sessionState> конфигурационного файла.

Далее SessionStateModule сохраняет состояние сессии в хранилище и удаляет ее из HttpContext вместе с идентификатором сессии. Если придет новый запрос, SessionStateModule восстановит состояние сессии в HttpContext. С первого взгляда это может показаться лишним, зачем, мол, что-то удалять и снова восстанавливать? Но не забывайте, что экземпляры HttpApplication (и, соответственно, HttpContext, экземпляр которого содержится в HttpApplication) хранятся в пуле. И поэтому, если придет запрос от другого клиента, нам не нужно будет сначала удалять состояние старой сессии, а затем восстанавливать.

ПРИМЕЧАНИЕ

Если использовать в качестве хранилища сессий SQL Server или State Server, то никакого события об окончании сессии не придет. Это логично, ведь если даже сессия вашего приложения будет уничтожена или будет выгружен сам рабочей процесс, данные все равно останутся не тронутыми. Это функциональность очень полезна, когда Web Services объединяются в так называемые “Фермы” (Web Farm), когда несколько машин, нагрузка по которым распределяется через технологию Load Balansing, образуют один глобальный Web-сервис. Но в этой, с первого взгляда, очень полезной функциональности кроется довольно существенная опасность. Дело в том, что как уже описывалось выше, рабочий процесс может быть удален, как только у него случится внутренний сбой. Соответственно, если у вас используется всего одно Web-приложение, работающее с SQL Server, то никто не сможет послать ему команду об осбовождении данных и удалении записей из таблиц. Именно для решения этой проблемы в поставку .NET входят *.sql файлы (они находятся в корне каталога, где установлен Framework). Эти файлы создают базу, в которой будут храниться состояния сессий. Но вместе с базой устанавливается и SQL-задание (JOB – действие, которое активизируется по расписанию). Это задание смотрит время последнего подключения и, если был привышен временной лимит, задание считает, что данная сессия более не нужна, и удаляет данные из базы. На самом деле, вам в любом случае нужно будет выполнить эти скрипты, ибо они создают базу, с которой будет работать SqlSessionStateStore (если вы, конечно, не хотите устанавливать все вручную). Так что стоит упомянуть одну важную особенность. Дело в том, что существуют два установочных сценария, InstallSqlState.sql и InstallPersistSqlState.sql. Разница между ними в том, что первый устанавливает TempDB, базу, которая будет унижтожена при выключении компьютера. Второй сценарий, InstallPersistSqlState.sql, устанавливает полноценную БД ASPState.

Еще один достойный рассмотрения модуль – SessionIDModule. Он отвечает за процесс создания идентификатора сессии для выполняющегося за ним модуля SessionStateModule. Если используется “cookieless” сессия (значение атрибута cookieless секции <sessionState> равно true), то этот модуль подписывается на перехват события BeginRequest. В обработчике из http-заголовка “AspFilterSessionId”, созданного, как было сказано выше, фильтром aspnet_filter.dll, извлекается номер сессии. Обработчик записывает полученное значение в HttpContext.Items с ключом “AspCookielessSession”. Если же значение cookieless было равно false (это означает, что номер сессии будет записан в cookie, и будет передаваться в специальном http-заголовке “Cookie”), данный модуль ничего перехватывать не будет, а идентификатор сессии будет выбираться непосредственно из модуля SessionStateModule.

ПРИМЕЧАНИЕ

Как вы могли догадаться, порядок регистрации модулей в конфигурационном файле тоже имеет значение. Ведь если бы модуль SessionIDModule стоял после SessionStateModule, то он и подписался бы на событие BeginRequest позднее, чем SessionStateModule. В таком случае ни о каких cookieless-сессиях не могло бы быть и речи.

Модуль SessionIDModule появится только в ASP.NET 2.0 (на момент написания этой статьи мне была доступна бета-версия Visual Studio codename Whidbey). До этого он был интегрирован с модулем SessionStateModule. Хорошо это или плохо (особенно, если принимать предыдущее замечание), решать вам, но знать заранее не помешает.

Завершающим модулем в цепочке всегда ставится DefaultAuthenticationModule. Он не указывается ни в каких конфигурационных файлах, так как автоматически добавляется классом конфигурации HttpModulesConfiguration. Предназначен этот модуль для создания IPrincipal (используемого по умолчанию). Такой принципал не имеет ни имени, ни типа аутентификации, ни ролей, и используется только потому, что в ASP.NET-приложениях свойство HttpContext.Principal не может возвращать null (подробнее про безопасность можно почитать в статье Тимофея Казакова "Механизмы безопасности в .NET", опубликованной в нашем журнале, #4’2003.

Формирование конвейера

Следующий этап инициализации объекта HttpApplication – формирование массива действий, которые будут им последовательно выполнены.

На рисунке 4 представлены события HttpApplication в том порядке, в котором они будут вызваны.


Рисунок 4. Порядок исполнения “шагов” HttpApplication.

В ASP.NET 1.1 некоторых показанных на рисунке событий нет, так как они появятся только в ASP.NET 2.0. Так что вы можете не удивляться, если пока не найдете о них ничего в документации. Описание событий для версий 1.1 и ниже доступно в MSDN, поэтому я привел пояснения только к тем событиям, которые будут доступны в новой версии.

На этом процесс инициализации объекта HttpApplication заканчивается. После этого инициализированный объект начинает обработку запросов.

Обработка запроса


Рисунок 5. Вызов метода HttpApplication.BeginProcessMessage.

HttpRuntime вызывает метод HttpApplication.BeginProcessMessage. Этот метод является реализацией интерфейса IHttpAsyncHandler, и используется для инициализации асинхронного вызова. После этого экземпляр HttpApplication начинает поочередно выполнять действия, список которых составлен на предыдущем этапе. Именно в этот момент вызываются обработчики событий, приведенные на рисунке 4, в модулях (Http Modules). Вы наверняка заметили неописанные действия MapHandlerExecutionStep, CallHandlerExecutionStep, CallFilterExecutionStep? Я опишу их подробнее.

MapHandlerExecutionStep – на этом шаге создается объект-обработчик полученной информации, то есть класс, реализующий IHttpHandler. На рисунке 6 показана UML-диаграмма создания этого обработчика.


Рисунок 6. Создание обработчика.

По запросу, посланному пользователем (*.asmx, *.ashx, *.aspx и т.д.), создается фабрика обработчиков (IHttpHandlerFactory). Все фабрики записаны в секции <httpHandlers>. Далее создается фабрика протоколов, используемых при запросе. В случае Web-сервиса этой фабрикой является SoapServerProtocolFactory. С помощью созданного экземпляра ServerProtocolFactory создается объект ServerProtocol, который передается конструктору обработчика. После создания ссылка на обработчик помещается в свойство HttpContext.Handler.

Для регистрации обработчиков используется секция <httpHandlers> конфигурационного файла. Чтобы добавить обработчик, нужно создать подсекцию <add> с атрибутами, приведёнными ниже:

  • Verb -тип запроса (PUT, GET или POST);
  • Path - путь или маска (например: *.asmx, service1.asmx);
  • Type - полное имя типа обработчика.

Имеется также возможность управлять созданием обработчиков. Для этого вместо обработчиков в секции <httpHandlers> регистрируются их фабрики (классы, реализующие интерфейс IHttpHandlerFactory). Так как фабрика создает нужный впоследствии обработчик, то, реализовав свою собственную фабрику, можно контролировать и регулировать процесс создания обработчиков. Обычно в machine.config указываются именно фабрики обработчиков (WebServiceHandlerFactory, HttpRemotingHandlerFactory, PageHandlerFactory и т.д.).

ПРИМЕЧАНИЕ

Если вы регистрируете обработчик, а не фабрику, то в HttpApplication для него создается HandlerFactoryWrapper. Вероятно, это сделано разработчиками ASP.NET из соображений единообразия и не несет дополнительной функциональности.

CallHandlerExecutionStep – это вызов обработчика, созданного на предыдущем шаге. На рисунке 7 показана диаграмма, демонстрирующая этот вызов (на примере вызова Web-сервиса, WebServiceHandler). Экземпляр этого класса занимается сериализацией и десериализацией SOAP-сообщений и, конечно же, вызовом Web-метода.


Рисунок 7. Вызов Web-метода.

В процессе выполнения обработчик обращается к объекту HttpRequest для получения входящих данных и заголовков HTTP-запроса. На рисунке 8 показано, что происходит при этих вызовах внутри класса HttpRequest.


Рисунок 8. Загрузка данных запроса в классе HttpRequest.

HttpRequest в цикле вызывает метод HttpWorkerRequest.ReadEntityBody, дочитывая входящую информацию, посланную в теле POST-запроса. После этого он фильтрует входящий поток. Этот фильтр может быть установлен в свойстве HttpRequest.Filter. Затем полученные данные десериализуются и вызывается Web-метод. На рисунке 7 отмечено, что на данном этапе может быть задействована COM+-транзакция. Это зависит от свойства TransactionOption атрибута WebMethodAttribute Web-метода. Далее в выходной поток сериализуется ответ Web-сервиса.

Тут я хочу упомянуть о еще одной маленькой, но очень важной детали. Часто в форумах, посвященных ASP.NET, можно услышать вопрос “А почему в моей реализации IHttpHandler значение сессии равно null?”. Дело в том, что если вашему обработчику нужно работать с состоянием сессии, он должен реализовать интерфейс IRequiresSessionState. Данный интерфейс не имеет ни методов, ни свойств, ни событий, и является своеобразным маркером. Модуль SessionStateModule, проверив, что текущий обработчик реализует этот интерфейс, немедленно сообщает HttpApplication о прекращении асинхронной обработки события AcquireRequestState, и HttpApplication, в свою очередь, начинает исполнять его последовательно.

CallFilterExecutionStep – вызов фильтров исходящего потока (HttpResponse.Filter). На рисунке 9 представлено, что происходит при этом.


Рисунок 9. Окончание обработки запроса в классе HttpResponse.

Как видно из диаграммы (см. рисунок 9), именно здесь вызываются последние события HttpApplication PreSendRequestHeaders, PreSendRequestContent в цепочке делегатов.

Завершение работы HttpApplication

Вот мы и добрались до этапа завершения работы HttpApplication и освобождения ресурсов. Отработавший экземпляр HttpApplication помещается в пул таких же объектов для того, чтобы в следующий раз не создавать его заново, повторяя достаточно большой процесс инициализации. Но если максимальный размер пула уже достигнут, а он, кстати, “как показывают опыты советских ученых”, имеет жестко определённое значение, равное 100 (это можно увидеть в методе RecycleNormalApplicationInstance класса HttpApplicationFactory при помощи любого дизассемблера или декомпилятора), то объект в пул не помещается и уничтожается. При уничтожении объекта вызывается метод IHttpModule.Dispose для всех модулей, используемых приложением.

Заключение

Надеюсь, что этот материал поможет вам разобраться в механизмах работы ASP.NET и более осмысленно использовать эту технологию в своей работе. Хочу выразить особую благодарность следующим людям: моему брату, Игорю Сухову, за неоценимую помощь в написании статьи, и Тимофею Казакову - за предоставление академической информации и конструктивную критику.

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 3 | Автор: ave_maria
Добавлено:21.02.2008 / 11:12
Sypper, spasibo za stol' bistriy otvet!!!! i iy ochen im dovol'na!!!!!!!!!!

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Кодирование -Раскодирование строк | Автор: Игорь Голов
Добавлено: 20.02.2008 / 18:08 | ответов: 11 | просмотров: 176

Нужно кодировать.раскодировать строки (это требуется для сохранения особых настроек)

Алгоритм Rinjdael для работы со строками подойдёт?
И подскажите, пожайлуста, в какую сторону дальше копать...
Спасибо!

Ответить на это сообщение | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 1 | Автор: Игорь Голов
Добавлено:20.02.2008 / 18:15
Да, и если нетрудно, подскажите, пожайлуста, как реализовать Rinjdael средствами Студии.

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 2 | Автор: 5acred Phoenix
Добавлено:20.02.2008 / 18:33
Смотрите в сторону пространства имён System.Security.Cryptography

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 3 | Автор: Игорь Голов
Добавлено:20.02.2008 / 18:53
Шифрование строки по алгоритму DES
Алгоритм выложен на абстрактном языке.
Когда разберусь с переводом в код - выложу текст программы здесь. :)

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 4 | Автор: 5acred Phoenix
Добавлено:20.02.2008 / 21:55
Алгоритм выложен на абстрактном языке.

Гы-гы))) Это си-шарп

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 5 | Автор: EROS
Добавлено:21.02.2008 / 00:18
Дожили... C# уже стал абстракным... куда мир катится?

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 6 | Автор: Алексей
Добавлено:21.02.2008 / 03:20
http://kbyte.ru/Expert/Show.aspx?id=27

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 7 | Автор: Игорь Голов
Добавлено:21.02.2008 / 11:12
Однакось вот обещанная реализация в [urlhttp://kbyte.ru/code/Show.aspx?id=116&lang=ru]нашем Кодообменнике[/url]
Сорри, если кого - то обидел - я не со Зла.... :)
Если это С# - то это вообще здорово!

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 8 | Автор: Игорь Голов
Добавлено:21.02.2008 / 11:15
Упс!
Ссылка на обещанный код

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 9 | Автор: Игорь Голов
Добавлено:21.02.2008 / 17:42
Дожили... C# уже стал абстракным... куда мир катится?


Не хочу давать долгосрочных прогнозов, но судя по всему мир катится к тому, что VB .NET - наше всё! (с) :)

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 10 | Автор: EROS
Добавлено:22.02.2008 / 08:02
судя по всему мир катится к тому, что VB .NET - наше всё!

:-))) Неее, этому не бывать...

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Ответ # 11 | Автор: Игорь Голов
Добавлено:22.02.2008 / 10:21
:-))) Неее, этому не бывать...


Ну тады поделим Пространство... :))

Добавить ответ | Посмотреть эту тему на сайте | Форум Kbyte.Ru


Наверх

 

Последние статьи

Как узнать размер базы данных MySQL через php
Автор: Николай Рудченко | добавлено: 14.02.2008 / 13:01 | просмотров: 59

В этой небольшой статье вы узнаете, как получить размер вашей базы данных (БД) MySQL используя язык программирования PHP.

Взаимодействие с другими сайтами через HTTP (HttpWebRequest и HttpWebResponse)
Автор: Немиро Алексей | добавлено: 27.07.2007 / 14:01 | просмотров: 2870

В данной статье речь пойдет о том, как можно программно заполнить и отправить Web-форму, а также получить результат с использованием довольно простых классов - HttpWebRequest и HttpWebResponse.

Работа с SQL – Запросы
Автор: Хабибулин А. (aka Bille Gates) | добавлено: 22.07.2007 / 04:43 | просмотров: 5347

В данной статье рассмотрены часто используемые SQL-запросы и приведены примеры их использования.

Использование XML.Serialization
Автор: Немиро Алексей | добавлено: 19.07.2007 / 15:38 | просмотров: 1484

В данном обзоре речь пойдет об использование XML.Serialization в .NET и ее применении на примере сохранения и считывания настроек программы с использованием синтаксиса языка Visual Basic .NET.

Выбор языка программирования для научных работ (2-я редакция)
Автор: Юдин С. Ю. | добавлено: 15.03.2007 / 02:49 | просмотров: 4142

Идея написания этой статьи возникла после того, как на одном из сайтов по физике http://physics.nad.ru/aniboard/messages/291.html я обнаружил интересный алгоритм моделирования движения тела в поле постоянной напряженности по различным направляющим. Вернее, меня заинтересовал не весь алгоритм, т.к. основа их всех одна (принцип Даламбера, если не считать квазиалгоритма с применением уравнений Лагранжа 2-го рода) и различаются они только способом определения реакций в месте соприкосновения тел. ...

 

Статьи на Kbyte.Ru

Наверх

 

Интересные коды и решения

Как разрешить вводить в TextBox только цифры?
Дата добавления: 04.08.2006 / 16:55 | просмотров: 1821 | платформа: ASP .NET (VB)

Как узнать IP-адрес текущего посетителя?
Дата добавления: 31.07.2006 / 15:34 | просмотров: 2014 | платформа: ASP .NET (VB)

Выравнивание формы по центру экрана
Дата добавления: 31.07.2006 / 12:12 | просмотров: 1073 | платформа: VB

Как узнать размер открытого файла?
Дата добавления: 31.07.2006 / 12:43 | просмотров: 1173 | платформа: VB

Округление до десятых, сотых, тысячных и т.д.
Дата добавления: 04.02.2007 / 21:09 | просмотров: 1789 | платформа: VB

Как загрузить текстовой файл целиком?
Дата добавления: 31.07.2006 / 17:12 | просмотров: 1088 | платформа: ASP .NET (VB)

Как расчитать возраст из даты рождения?
Дата добавления: 24.03.2007 / 12:06 | просмотров: 943 | платформа: VB .NET

Анализ даты стандарта MM/DD/YYYY и MM/DD/YY
Дата добавления: 24.03.2007 / 10:59 | просмотров: 1076 | платформа: RegEx

Проверить корректность E-Mail (стандартный способ)
Дата добавления: 21.08.2006 / 20:23 | просмотров: 1346 | платформа: ASP .NET (VB)

Как обработать клиентские события элемента управления?
Дата добавления: 17.08.2006 / 17:50 | просмотров: 1422 | платформа: ASP .NET (VB)

 

Универсальные коды на Kbyte.Ru

Наверх

 

Юмор на Kbyte.Ru

Три летучие мыши висят вниз головами.
Вдруг одна - рраз - вверх головой.
(1) - ???
(2) - А, это у нее обморок!

 

Рейтинг: 653
Всего голосов: 800
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Спрашивает учитель на уроке математики у Гоги:
- Гоги, а чему равна сумма квадратов катета?
- Квадрату гипотенузы!
- A чем докажешь?
Гоги:
- Мамой клянусь!!!

 

Рейтинг: 356
Всего голосов: 520
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Знаете, что такое Plug&Play в Windows? "Нашёл у вас не знаю что, подайте мне диск не знаю с чем".

Прислал MAGICIAN

 

Рейтинг: 1016
Всего голосов: 1493
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Приходит программер домой, к нему подбегает кошка и начинает усиленно ластиться, лизать руку, мурчать и т.д.Жена, увидев это, спрашивает:
- Что это вдруг случилось с кошкой? Чего она руку-то лижет?
- Как чего? Мышкой пахнет...

 

Рейтинг: 196
Всего голосов: 339
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Учительница повела детей в лес на экскурсию. И вдруг говорит:
- Смотрите, дети, кого я нашла! Кто это весь в иголках?
- Не знаем.
- Вспомните, мы про него песни пели и стихотворения учили.
- Ах вот ты какой, дедушка Ленин!

 

Рейтинг: 694
Всего голосов: 931
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

С тех пор, как я попробовала новый "Dove", моя кожа помолодела, стала нежной, приятной на ощупь. Поры раскрылись.
Я почувствовала прилив бодрости, новых сил! Даже сама удивилась! Хотя на вкус - мыло как мыло...

 

Рейтинг: 119
Всего голосов: 201
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Приходит учительница Вовочки к нему домой и жалуется папе, ваш сын нарисовал на моём столе муху я её била, била даже руку сломала. Это ещё ничего, отвечает папа он в ванне нарисовал крокодила, я так испугался, что даже из нарисованной двери выбежал.

 

Рейтинг: 215
Всего голосов: 324
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Пора Остановиться Если:

- В самолете или поезде уделяете больше внимания notebook’у, сдав ребенка в багаж.
- Ваша жена говорит, что вы в последнее время мало общаетесь, поэтому вы решили купить второй компьютер и сделать дома LAN, что бы вы могли поболтать по аське.
- Решаете остаться на работе или в институте ещё на пару годиков из-за бесплатного интернета.
- думаете, что неудачники и бедняки это люди, которые имеют MODEMы на 28.8 kB/s.
- Используете смайлики в обычной бумажной почте.
- Не знаете пол ваших трех лучших друзей, потому что у них нейтральные ники, а спросить вам не приходило в голову.
- Хотите улыбнуться, наклоните голову на 90 градусов.
- Купание в ванне называете "downloading".
- Решил поменять кресло на унитаз.
- Выключая MODEM, чувствуете себя так, как будто только что предали лучшего друга.
- Новым знакомым представляетесь как "вася @ маил точка ру".
- Ваше сердце колотится быстрее, когда в телевизоре видите интернетовский адрес какой-либо компании.
- Прежде чем покинуть комнату, поставите динамики на полную громкость, что бы не пропустить момент прихода новой почты.
- Все ваши знакомые и друзья имеют в своём имени знак "@" (напр. Миш@, С@ш@).
- Ваше домашнее животное имеет личную домашнюю страничку.
- Не можете позвонить родителям – у них нет MODEMа.
- проверяете e-mail, если новых сообщений нет – проверяете снова.
- Часа в два ночи пойдете в туалет и останетесь у компьютера до утра.
- Жена вам раз и навсегда запретила брать notebook в постель.
- Ваших детей зовут: девочку - Altavista или VISA, мальчика - Yahoo или Chat...
- Кличка вашей собаки Linux или Fox.
- Зимой вообще не выключаете монитор – от него теплее.
- используете HTML-TAGи в Microsoft Wordе.
- думаете, что люди, которые используют "Microsoft Photo Editor" вместо "Corel Photopaint" идиоты.
- Любите Билла Гейтса.
- Отслеживаете ошибки ошибок.(ошибочная ошибка = ничего ошибочного)
- Лучше реагируете на "go2work&earn4me_some$.com", чем на "иди на работу и заработай для меня немного денег, давай!"
- У вас не зависают Windows.
- Умеете читать и без проблем понимаете машинный код.
- Каждых два-три часа чистите proxy cashe.
- В бумажных формулярах инстинктивно заполняете:
Имя и фамилия: (ваш ник, Alias)
Компания: N/A
Возраст: од...до(напр. между 18 и 25)
Дети: так же (напр. От 1 до 3)
Месячный заработок: (серийный номер)
- Иногда говорите с телевизором.
- Программа имеет физический вес „весит“.(напр. 150 килограмм)
- Самая маленькая часть чего угодно - бит.
- Не знаете что это за служба „Tech Support“.
- Вы там работаете, но на телефонные звонки не отвечаете, потому что "в трубке" у всех сплошные вопросы и проблемы.
- Компьютер – бестолковое железо, пока не подключен на интернет.
- Рекламные проспекты в реальном почтовом ящике - SPAM. Относится и к повесткам и фактурам.
- жалко, что книги нельзя выделить и скопировать.
- Вас возбуждает чтение log-файлов squid'a.
- познакомясь с девушкой, сразу спрашиваете какой у нее IP-адрес.
- IP-адрес динамический, значит девушка легкого поведения.
- Коллеги вам говорят, что у вас все работает как dev/shit, через dev/ass, у вас кривые dev/hands и маленький dev/brain. Не знаете о чем это они.
- в Linuxе напишете "$ make love" или "$ man woman".
- К вам подойдет сын и спросит: "Как устроен телевизор?", то вы ответите: "RTFM!". А если сын спросит: "man TVSet". Подробно ему все расскажете, даже если он уже не будет этого хотеть.
- Не ходите в церковь, потому что не знаете URL.
- Постоянно вам хочется и иногда пишите:
„let x = 7;“
или
„if (value == 0)
return value;
else
return 0;".
Fi
- У вас в машине стоят факс, принтер, телетайп и SWIFT.
- Вашего ребенка сначала учите считать до 256.
- У телевизора есть монитор и LPT.
- Для вас OS/2 = PS2
- Школьная доска = монитор(мой учитель) ?
- Для вас LPT = LTP.
- Для вас BASIC = BIOS.
- Ваши зрачки увеличиваются, когда видите "CONNECT 17689/VOICE".
- Сможете пропищать хотя бы на 1200.(MODEM’овый тон)
- Не мечтаете о MODEMе на 115200.
- Имеете такой MODEM.
- Уже не можете определить время на механических часах.
- Мечтаете о приборе "assessometr".
- Пишете книгу с рабочим названием "Контрольные системы для Ядерных Электростанций на базе Windows 95"
- Долго решаете что лучше: „налепить обои или растянуть одну картинку.“
- В магазине с умным видом: "Коробочку хард дисков, пожалуйста".
- WWW,FTP,HTTP,DHTML,URL,SPOOL,MODEM,IRQ,PPP,DOS – не сокращения, а нормальные слова.
- Имеете татуировку "This body best viewed with Internet Explorer 4.0 or higher".
- При ДТП инстинктивно ищете кнопку "BACK".
- думаете, что телевизор имеет плохое разрешение. Примерно 640 на 480
- пишете в С++ программу для калькулятора.
- Вы написали вирус для калькулятора.
- Как только это прочитаете, сразу распечатаете.
- Используете слова и выражения типа:
Internet Exploder
Outloop Exchanger
Netscape Complicator
Teer To Teer NetWork
10,578 kegabytes
2 zillion
300 MHz RAM
Cursing flasher
CONSYS.FIG
SETUP.EXERSIZE
Microword Soft
Microwave Windows
Netscape Explorer
Microscope Exploiter
Newscape
Outlook Exposure
Corel WordPerfect для IBM
Megadrives
Windows 94
Backsplash
Backstage
Backcase
SoaperCase
LoverCase
CaseSeniletive
CaseInsectitive
...It is NOT safe for me to turn off my computer...
200 horse power hard drive
Cadle Mobem
Pinteum
Mudem
Momed
386 Pentium
486DX Pentium
US Robotics Sportscaster modem
Unnecessary disk space
__
User Unknown

 

Рейтинг: 228
Всего голосов: 354
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

История об узком профессиональном мышлении.
Офис-менеджер попросила посидеть за неё в приёмной. Сижу. Заходит тётенька и задаёт вопрос в лоб:
- У вас мыши есть?!
Я, недоумевая, нафига ей наши мыши:
- Только ЮЭСБИшные!
- КАКИЕ-КАКИЕ??!!! - грозно спрашивает она.
Кое-как мы друг друга поняли. Оказалось, что тётка с эпидемстанции пришла мышей на складе травить!

 

Рейтинг: 911
Всего голосов: 1289
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Идет программист по улице тут ему на голову падает кирпич. Тетрис, подумал программист...

 

Рейтинг: 203
Всего голосов: 320
Оцените этот анекдот через E-Mail:
Выберите оценку: 5 | 4 | 3 | 2 | 1

 

Весь юмор на Kbyte.Ru

Наверх


Выпуск подготовил: R-KDR-19826

Редактор: Немиро Алексей

Copyright (c) Nemiro AS, 2005-2007


В избранное