Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Работа с Label Добавлено: 10.07.08 13:07  

Автор вопроса:  vbSerGanT
Встретил недавно такую проблему.
Хотел сделать тень у надписи, а прозрачность не устанавливается. Имеется ввиду метка под меткой на некотором смещении и другим цветом.

Ответить

  Ответы Всего ответов: 12  

Номер ответа: 1
Автор ответа:
 Boconon



ICQ: 216390557 

Вопросов: 25
Ответов: 71
 Web-сайт: microsoft.com
 Профиль | | #1
Добавлено: 10.07.08 19:21
Private Sub Form_Load()
 Label1.Caption = "VB is Easy!"
 Label2.Caption = "VB is Easy!"
 Label1.BackStyle = vbTransparent
 Label2.BackStyle = vbTransparent
 Label1.ForeColor = vbRed
 Label2.ForeColor = vbBlack
 Label1.FontBold = True
 Label2.FontBold = True
 Label1.Left = Label2.Left + 50
 Label1.Top = Label2.Top + 50
 Label2.ZOrder (1)
End Sub

Ответить

Номер ответа: 2
Автор ответа:
 vbSerGanT



Вопросов: 6
Ответов: 22
 Профиль | | #2 Добавлено: 17.07.08 08:47
Это примерy на VB6, а нужен на .NET

Ответить

Номер ответа: 3
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #3 Добавлено: 20.07.08 02:10
Use System.Drawing

Ответить

Номер ответа: 4
Автор ответа:
 BG(Алексей)



Вопросов: 26
Ответов: 295
 Профиль | | #4 Добавлено: 20.07.08 05:56
Private Sub Label1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Label1.Paint
        ;Dim Br = New SolidBrush(Color.FromArgb(70, Me.Label1.ForeColor))
        ;Dim shadowrect As Rectangle = Me.ClientRectangle
        shadowrect.X += 5
        shadowrect.Y += 5
        e.Graphics.DrawString(Me.Label1.Text, Me.Label1.Font, Br, shadowrect)
    End Sub

Ответить

Номер ответа: 5
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #5 Добавлено: 20.07.08 12:15
Dim Br = New SolidBrush(Color.FromArgb(70, Me.Label1.ForeColor))


А Dispose Пушкин вызывать будет?

Ответить

Номер ответа: 6
Автор ответа:
 BG(Алексей)



Вопросов: 26
Ответов: 295
 Профиль | | #6 Добавлено: 20.07.08 19:17
А Dispose Пушкин вызывать будет?


Нет не Пушкин, GC.
Да и зачем платить дважды одну цену?

Переменная обьявлена на уровне процедуры, вот и жить она будет во время работы процедуры. Да и GC сделает это намного правильней.

В качестве теста приведу пример.
Написал я недавно прогрессбар в котором, использовалось много графических обьектов. Естественно я их диспосил.
Отправил я этот прогрессбар своему авторитетному Сенсею на проверку, дабы он взглянул на мои ошибки.
Его приговор меня шокировал. Он сказал, что бы я повыносил все графичекские обьекты из процедур и убрал все диспос методы, переопределил Finalize, а так же ознакомился с работой GC.
Я все это проделал и решил протестировать первичный вариант прогрессбара, а затем второй.
Результат первого варианта(с диспосом) был такой:
Запустил я его нон-стоп на 40 мин и следил за памятью.
Оказалось придраться было не к чему.
Запустил второй вариант с теми же условиями, но без диспос метода.
Сдесь результат отличался.
В течении первых 3-4 минут память выросла аж на 10MB.
потом, резко свалилась до начального значения.
В течении вторых 4-5 минут память выросла аж на 8-9MB.
Опять свалилась и на протяжении оставшегося (из отведенного для теста) времени, изменялась максимум на 1-2MB.

Результат работы GC с управляемыми рессурсами просто на высшем уровне, чего не скажешь о неуправляемых рессурсах. Там нужно все диспосить.

Сдесь все хорошо описанно:
http://www.rsdn.ru/article/dotnet/GC.xml
http://dotsite.spb.ru/Publications/Publication137.aspx
http://dotsite.spb.ru/Publications/Publication132.aspx

Ответить

Номер ответа: 7
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #7 Добавлено: 20.07.08 20:24
Нет не Пушкин, GC.
Да и зачем платить дважды одну цену?

Начинается...
Обрывы сессий не мучают случайно?

Переменная обьявлена на уровне процедуры, вот и жить она будет во время работы процедуры.

Жить объект (не переменная) будет с момента его создания и до того момента как GC выполнит физическое удаление объекта.

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

АААА, жесть!! КТО??? КТО ЭТОТ СЕНСЕЙ???
Я могу предположить что как минимум Андерс Хейлсберг или Джеффри Рихтер. Не меньше!

Я все это проделал и решил протестировать первичный вариант прогрессбара, а затем второй.
Результат первого варианта(с диспосом) был такой:
Запустил я его нон-стоп на 40 мин и следил за памятью.
Оказалось придраться было не к чему.
Запустил второй вариант с теми же условиями, но без диспос метода.
Сдесь результат отличался.
В течении первых 3-4 минут память выросла аж на 10MB.
потом, резко свалилась до начального значения.
В течении вторых 4-5 минут память выросла аж на 8-9MB.
Опять свалилась и на протяжении оставшегося (из отведенного для теста) времени, изменялась максимум на 1-2MB.

Что с чем сраниваем? Среднюю температуру по больнице со скоростью движения света в манной каше?

Результат работы GC с управляемыми рессурсами просто на высшем уровне

Это ты мне будешь рассказывать? :)

чего не скажешь о неуправляемых рессурсах.

А кто тебе сказал что Brush это управляемый ресурс? Пан Рихтер?

Там нужно все диспосить.

Грубо говоря "диспозить" нужно все что имеет метод Dispose.



Вобщем небольшой разбор полетов.

В принципе, предположить что Brush является неуправляемым ресурсом можно и без рефлектора, так как он является объектом GDI+.

Все очень просто, вот что присутствует в конструкторе SolidBrush:

    Dim status As Integer = Gdip.GdipCreateSolidFill(Me.color.ToArgb, zero)

GdipCreateSolidFill - это вызов функции из библиотеки gdiplus.dll.

Что происходит в методе Dispose класса Brush:
Gdip.GdipDeleteBrush(New HandleRef(Me, Me.nativeBrush))

Нужно объяснять что это тоже является выходом в unmanaged код?

И пока Dispose вызван не будет, Brush, на которой указывает хендл nativeBrush As IntPtr будет висать в памяти.

Каким образом происходит развитие если Dispose не вызвать.

Да, как ты сказал, объект будет доступен только в пределах процедуры.
Далее (не сразу после выхода из процедуры, разумеется) запускается сборщик мусора, и видит, что есть некий объект, на которой никто не ссылается, и котороый по сути является мусором.
Но также сборщик мусора видит что у объекта определен финализатор, поэтому объект помещается в отдельную очередь на финализацию.
Далее у объекта вызывается финализатор, в финализаторе, раузмеется, принудительно вызовется Dispose (в этом можно убедиться, посмотрев на его код в рефлекторе):
Protected Overrides Sub Finalize()
    Try
        Me.Dispose(False)
    Finally
        MyBase.Finalize
    End Try
End Sub

В методе Dispose будут освобождены все неуправляемые ресурсы (см выше, я описал как это делается).
И физически объект будет удален только при следующей сборке мусора потому что на него еще имеется ссылка из очереди финализации.
То есть для этого объекта сборка мусора будет проходить дважды.

Что же будет если вызвать .Dispose принудительно?
В этом случае
1) Освободятся unmanaged ресурсы
2) Объект будет удален из очереди финализации (убедиться в этом можно опять же, посмотрев исходный код метода Dispose)
Public Sub Dispose()
    Me.Dispose(True)
    GC.SuppressFinalize(Me)
End Sub


Останутся только управлемые ресурсы которые будут освобождены при следующей сборке месора, при этом у этого объекта уже не будет вызываться финализатор поскольку он был удален из очереди.





Подытоживая все сказанное.
Если объект реализует IDisposable, то после работы с ним нужно вызвать метод Dispose (или поручить это блоку Using, что более надежно).
Если этого не сделать, Dispose все равно будет вызван автоматически, но намного позже и это будет связано с определенными дополнительными затратами.

Финализатор как правило имеет смысл делать только в сценарии с Disposable-объектом, когда объект работает с неуправляемыми ресурсами.
Если объект оперирует только управляемыми ресурсами то финализатор делать смысла нет - все упралвяемые ресурсы без проблем будут освобождены сборщиком мусора.

Далее медитировать на Рихтера до полного просвещения.

Сдесь все хорошо описанно:
http://www.rsdn.ru/article/dotnet/GC.xml
http://dotsite.spb.ru/Publications/Publication137.aspx
http://dotsite.spb.ru/Publications/Publication132.aspx

Описано может быть и хорошо, но тебе это похоже мало чем помогло...

Ответить

Номер ответа: 8
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #8 Добавлено: 20.07.08 20:50
BG(Алексей), ты не прав.. В любой книге где рассказывается о работе с GDI говорится о том, что вызов Dispose для этих объектов обязателен!. И как уже сказал Steel Brand правильнее всего для этих объектов использовать блок Using, это будет гарантированное удаление объекта и освобождение ресурсов.

Ответить

Номер ответа: 9
Автор ответа:
 BG(Алексей)



Вопросов: 26
Ответов: 295
 Профиль | | #9 Добавлено: 20.07.08 21:08
EROS
А я и не говорил, что я прав.
Я хотел сказать, что GC справится с удалением обьекта.

Steel Brand
Спасибо большое за разжевывание конкретного примера.
Заметь, я не спорю, потому как я намеренно поднял эту тему, что бы получить конкретные обьяснения, которых мне не хватало.

Ты лучше обьясни мне обьясни почему моя база данных не хочет Апдэйтываться. Сейчас сформулирую вопрос и открою новую тему.
Спасибо.

Ответить

Номер ответа: 10
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #10 Добавлено: 20.07.08 23:48
Я уже ответил на вопрос, это предположение конечно, но наиболее вероятное по-моему.

Ответить

Номер ответа: 11
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #11 Добавлено: 21.07.08 08:45
Я хотел сказать, что GC справится с удалением обьекта.

GC справится только с удалением управляемых ресурсов, про неуправляемые он ничего не знает. Кроме того, принудительное удаление подобных объектов есть "правило хорошего тона". (имхо) Не стоит полагаться на GC в данном случае, потому что если где то в коде произойдет ошибка, то объекты остануться висеть в памяти, а это не есть хорошо. И напротив, блок Using гарантирует удаление объекта при любом стечение обстоятельств.

Ответить

Номер ответа: 12
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #12 Добавлено: 21.07.08 16:13
Не стоит полагаться на GC в данном случае, потому что если где то в коде произойдет ошибка, то объекты остануться висеть в памяти, а это не есть хорошо.


Ничего висеть не останется - с какой стати?
Объект становится недоступным, и дальше GC с ним разберется.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам