origin: http://blogs.msdn.com/b/jgoldb/archive/2010/06/14/memory-leak-hotfixes-for-wpf-3-5-sp1.aspx

 

 

Hopefully folks saw my related blog post Finding Memory Leaks in WPF-based applications .
In this post below I wanted folks to be aware that we released few other KB Articles (Hotfix) that address other various memory leaks reported in .NET 3.5 SP1. Some of these fixes made it to .NET 4.

1. KB981107 (See: http://support.microsoft.com/kb/981107)

This Hotfix fixes the following memory leaks in .NET 3.5 SP1 WPF-based applications.
Issue 1:
This affects an app that contains styles or templates that refer to application resources (via StaticResource or DynamicResource), and that creates a large number of elements that use these styles or templates but never need the actual value of the resource.  In this situation, the app can leak DeferredAppResourceReference objects, even after the elements themselves have been reclaimed.  (In addition, the app can leak WeakReferences and array space, similar to the issues described below.)

An example:  App resources define   <sys:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarHeightKey}">20</sys:Double>     This creates a resource that's used by any control that can display a horizontal scrollbar.  Creating a large number of such controls that never actually display their scrollbar will encounter the leak.

Issue 2:
This affects an app that creates a large number of short-lived elements with properties that are data-bound to a DependencyProperty of longer-lived elements. In this situation, the longer-lived elements maintain lists of WeakReference objects, used to notify the short-lived elements about property changes. The app can leak WeakReference objects and the array space to hold them, even after the short-lived elements have been reclaimed.

An example:   ListBoxItem binds its HorizontalContentAlignment property to a similar property on its governing ListBox.   An app that creates a large number of ListBoxItems (say by doing a large number of additions and deletions to the ListBox's ItemsSource) will encounter the leak.

Issue 3:
This issue affects classes derived from TreeView or Selector (including ListBox, ListView, Menu, DataGrid, and many others).   These classes register for an internal notification from the KeyboardNavigation class, used for controlling keyboard focus.   An app that creates a large number of these elements can leak WeakReference objects and the array space to hold them, even after the elements themselves have been reclaimed.
An example:  An app that creates a large number of short-lived ListBoxes will encounter the leak.  This can happen in a nested scenario, where an outer ListBox displays a collection that undergoes a large number of additions and deletions, and where each item is displayed using an inner ListBox.

These fixes are not included in NET4. We are considering this Hotfix also for NET4, but this decision has not been made, so stay tune.

2. KB967634: (See: http://support.microsoft.com/kb/967634 )

This fixes a memory leaks in .NET 3.5 SP1 WPF-based applications when using software 3D rendering involving a VisualBrush or DrawingBrush.
This fix is already included in .NET 4.

3. KB967328 (See: http://support.microsoft.com/Default.aspx?kbid=967328)

This Hotfix fixes memory leaks when a deferred resource isn't inflated due to the resource reference expression hooking up to the Inflated event on the resource dictionary entry.
If the resource dictionary is an application or theme dictionary, then these are essentially global and can cause these expressions to stay alive.
There are some discussions on this issue here.
This fix is already included in .NET 4.

 

posted @ 2010-07-26 13:05 江湖飘 阅读(60) 评论(0) 编辑
摘要: Origin: http://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspxThere are numbers of blogs that folks wrote about memory leaks in Microsoft .Net Framework ...阅读全文
posted @ 2010-07-26 13:03 江湖飘 阅读(199) 评论(0) 编辑
posted @ 2009-10-20 10:47 江湖飘 阅读(50) 评论(0) 编辑

 

In the last post, I wrote about how focus is generally managed in WPF - we have focus scopes to track a single element within that scope for logical focus, and then one of those elements is given physical, or keyboard focus.

Now, let's talk a little about how you can influence that programatically. First, you can always determine which element has logical focus in your application through the FocusManager.GetFocusedElement method -- pass it the window in question and it will return which element has logical focus in that window. Remember that logical focus != keyboard focus at all times -- toolbars and menus track their own focus so if you are currently interacting with a menu then the menu has physical focus. But in general, the following code will tell you which element WPF thinks has focus in the window:

IInputElement focusedElement = FocusManager.GetFocusedElement(thisWindow);

To determine whether this element has keyboard focus, we can check the IsKeyboardFocused property - if it's set to true, then that element currently has the keyboard focus (as well as being the logical focus for that focus scope).

Keyboard focus is most often set through runtime activity - the user clicks on an element, or uses the TAB key to move around the UI. You can also set it programatically a couple of ways. First, there is a Keyboard class in WPF which exposes several methods and properties. There is a Keyboard.FocusedElement read-only property which returns the current keyboard focused element, and there is a Keyboard.Focus method which attempts to change keyboard focus. It returns the element that now has focus - so you can check to see if your request was fulfilled or ignored. So, for example, you can change focus during your application initialization:

void OnLoaded(object sender, RoutedEventArgs e)
{
Keyboard.Focus(firstTextBox);
}

Notice that we uses the Loaded event - this is because no focus requests will be accepted prior to the element being initialized and loaded. That's the first place in the application where you can make focus changes.

When would setting focus fail? Well, it can fail for a lot of reasons, but the most common are:

  1. The element has Focusable = false
  2. The element has Enabled = false
  3. The element has IsVisible = false
  4. The element has not been loaded yet
  5. The currently focused element will not release focus.

That final one is important, changing focus involves potentially taking it away from an existing element - they receive a PreviewLostKeyboardFocus and LostKeyboardFocus event. If they handle the preview event, focus will not change.

You can also manipulate focus through programatic keyboard navigation - simulating the user pressing TAB to cycle through the focusable elements. This is controlled through the KeyboardNavigation class which is used when the user presses a key that changes focus (TAB, SHIFT+TAB, Up, Down, etc.).

Controls can set a TabIndex property assignment which determines the tabbing order. The default is to tab through them in order of declaration. You can also use the KeyboardNavigation.TabIndex attached property which works for any element - not just controls.

To control navigation, the KeyboardNavigation class has an attached property TabNavigation allowing you to change how navigation occurs within a container. You can set it to:

  1. Continue - each focusable element receives focus and the container is exited when the edge is reached.
  2. Cycle - focus does not leave the container but wraps around the edges
  3. Once - the container itself is treated as a single focusable element where only the first child receives focus
  4. Local - uses TabIndex locally within the container - independant of any outside elements.
  5. Contained - focus statys in the container but does not wrap (stays at edges when top/bottom are reached)
  6. None - no keyboard navigation allowed in the container

The default is Continue, but you can set the attached property on any element to change it for that element and any children. To see this in action, paste the following into your XAML editor of choice and change the ComboBox while tabbing through the TextBlock elements.

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Simple Focus">

<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="10" />
<Setter Property="Width" Value="100" />
</Style>
</Window.Resources>

<StackPanel>
<ComboBox x:Name="tabStyles" SelectedIndex="0" Focusable="False">
<sys:String>None</sys:String>
<sys:String>
Continue</sys:String>
<sys:String>Cycle</sys:String>
<sys:String>Once</sys:String>
<sys:String>Local</sys:String>
<sys:String>Contained</sys:String>
</ComboBox>

<TextBox TabIndex="1" />
<TextBox TabIndex="2" />
<StackPanel
KeyboardNavigation.TabNavigation="{Binding ElementName=tabStyles,Path=SelectedItem}">
<TextBox TabIndex="1" />
<TextBox TabIndex="2" />
</StackPanel>
</StackPanel>
</Window>

You can have the system ignore specific elements (but still allow them to have focus) by setting the KeyboardNavigation.IsTabStop="false" attached property. This will cause keyboard navigation to "jump" over the control as if it were not present.

Three methods are exposed by UIElement and FrameworkElement to programatically shift focus: Focus, MoveFocus and PredictFocus.

To force focus to a specific element, you can call Focus on it. For example, above we set the keyboard focus by calling Keyboard.Focus(), but the same effect can be achieved like this:

void OnLoaded(object sender, RoutedEventArgs e)
{
firstTextBox.Focus();
}

This method attempts to set focus using Keyboard.Focus(). If that fails, but the element is Focusable and enabled, it finds the focus scope for the element and sets logical focus there (so that keyboard focus will eventually end up on the control).

FrameworkElement.MoveFocus is used to change the keyboard focus in the application using the same algorithm as the TAB traversal. You pass in the direction (specified through a TraversalRequest object) and the method returns true/false to indicate success. Under the covers it actually uses the KeyboardNavigation class, but it's an easy way to push focus around the window:

firstTextBox.MoveFocus(
new TraversalRequest(FocusNavigationDirection.Next));

PredictFocus works the same way, but instead of actually shifting focus, it returns what would be the focused item if you were to execute MoveFocus.

So, up to this point, we've seen a lot of code to change focus. However, the most common request is to set initial focus to a specific control - remember that WPF doesn't do that by default. You can do it in code, just like the above example where we use the Loaded event. Or, it turns out you can do it in XAML too. The key to remember is that the FocusedElement of the main focus scope (the Window) is the one that will get initial focus. That is (by default) null, but you can set it in XAML using the attached property syntax. Using the above XAML example, we can supply a name for one of the TextBox controls and then a little data binding magic to set that onto the Window:

 

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Simple Focus"
FocusManager.FocusedElement="{Binding ElementName=tb2}">
...
<TextBox TabIndex="1" />
<TextBox x:Name="tb2" TabIndex="2" />
...
</Window>

Now when you run the application, focus is placed into the second text box in the window. This technique works great as long as the element you want to assign focus to is declared here in the same XAML file. However, a popular way to develop WPF applications is to separate out chunks of UI into separate UserControls. When you do that, the above trick fails -- even if you put the FocusManager.FocusedElement binding into the UserControl!

How we solve that is what we'll look at in the next post! Stay tuned...

Origin : http://www.julmar.com/blog/mark/PermaLink,guid,6e4769e5-a0b3-47b2-a142-6dfefd0c028e.aspx

posted @ 2009-10-20 10:38 江湖飘 阅读(319) 评论(0) 编辑

命令格式:Subst [Drive1:] [Drive2:Path]
作用:映射某磁盘中的文件到另一个磁盘。eg. Subst e: "C:\My Disk(E)"

删除操作:
Subst e: /D

顺便提一下可以用这个方法隐藏软盘A,方法如下:
在运行中输入:sysedit
C:AUTOEXEC.BAT文件中输入相应的命令,表示重启就运行批处理文件。

posted @ 2009-06-03 10:24 江湖飘 阅读(71) 评论(0) 编辑

贴个C++的运算符优先级表,给大家和自己有个参考吧!

Precedence Operator Description Example Associativity
1 ()
[]
->
.
::
++
--
Grouping operator
Array access
Member access from a pointer
Member access from an object
Scoping operator
Post-increment
Post-decrement
(a + b) / 4;
array[4] = 2;
ptr->age = 34;
obj.age = 34;
Class::age = 2;
for( i = 0; i < 10; i++ ) ...
for( i = 10; i > 0; i-- ) ...
left to right
2 !
~
++
--
-
+
*
&
(type)
sizeof
Logical negation
Bitwise complement
Pre-increment
Pre-decrement
Unary minus
Unary plus
Dereference
Address of
Cast to a given type
Return size in bytes
if( !done ) ...
flags = ~flags;
for( i = 0; i < 10; ++i ) ...
for( i = 10; i > 0; --i ) ...
int i = -1;
int i = +1;
data = *ptr;
address = &obj;
int i = (int) floatNum;
int size = sizeof(floatNum);
right to left
3 ->*
.*
Member pointer selector
Member pointer selector
ptr->*var = 24;
obj.*var = 24;
left to right
4 *
/
%
Multiplication
Division
Modulus
int i = 2 * 4;
float f = 10 / 3;
int rem = 4 % 3;
left to right
5 +
-
Addition
Subtraction
int i = 2 + 3;
int i = 5 - 1;
left to right
6 <<
>>
Bitwise shift left
Bitwise shift right
int flags = 33 << 1;
int flags = 33 >> 1;
left to right
7 <
<=
>
>=
Comparison less-than
Comparison less-than-or-equal-to
Comparison greater-than
Comparison geater-than-or-equal-to
if( i < 42 ) ...
if( i <= 42 ) ...
if( i > 42 ) ...
if( i >= 42 ) ...
left to right
8 ==
!=
Comparison equal-to
Comparison not-equal-to
if( i == 42 ) ...
if( i != 42 ) ...
left to right
9 & Bitwise AND flags = flags & 42; left to right
10 ^ Bitwise exclusive OR flags = flags ^ 42; left to right
11 | Bitwise inclusive (normal) OR flags = flags | 42; left to right
12 && Logical AND if( conditionA && conditionB ) ... left to right
13 || Logical OR if( conditionA || conditionB ) ... left to right
14 ? : Ternary conditional (if-then-else) int i = (a > b) ? a : b; right to left
15 =
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=
Assignment operator
Increment and assign
Decrement and assign
Multiply and assign
Divide and assign
Modulo and assign
Bitwise AND and assign
Bitwise exclusive OR and assign
Bitwise inclusive (normal) OR and assign
Bitwise shift left and assign
Bitwise shift right and assign
int a = b;
a += 3;
b -= 4;
a *= 5;
a /= 2;
a %= 3;
flags &= new_flags;
flags ^= new_flags;
flags |= new_flags;
flags <<= 2;
flags >>= 2;
right to left
16 , Sequential evaluation operator for( i = 0, j = 0; i < 10; i++, j++ ) ... left to right

http://www.cppreference.com/wiki/operator_precedence

posted @ 2009-04-01 12:25 江湖飘 阅读(284) 评论(0) 编辑
Code
如上代码,首先如果不在D的继承中,将一个父类(B或C)加上virtual关键字的继承的话,编译会出错,因为在D中会有两条路径继承A的f()函数,会产生冲突。

然后D的对象直接调用f()也会出错,会有二义性,解决方法是加上类的修饰符。

D d;
d.B::f();
d.A::f();

posted @ 2009-03-30 02:00 江湖飘 阅读(98) 评论(0) 编辑

最近我们在工作中碰到一个奇怪的问题,最后确定是多继承引起的指针漂移,跟C++对象模型有关。示意如下:

class A {...};
class B{...};
class AB : public B, public A {...}
...
AB *pab = new AB();
A* pa = (A*)pab;
B* pb = (B*)pab;

这时候你发现pa和pb的值是不一样的!它们中有一个跟pab是相等的,而另外一个产生了偏移。如果把AB的声明中A和B的顺序调换一下,则产生偏移的指针也会变为另外一个。

为了确定这是编译器做了转换的缘故,利用void指针愚弄编译器:
void *pv = (void*)pab;
pa = (A*)pv;

这时候pa的值倒是跟pab相等了,然而指向了错误的地方。从pab到pa的转换,依赖于路径的选择,让人不是很放心。还不知道把指针放入容器中再取出来,会不会出错。当然,上面使用了强制类型转换,在良好的程序中应该避免。如果只有隐式转换,可以得到正确的结果:

 std::vector<A*> v;
 //implicit type conversion
 v.insert(v.begin(), pab);
 void *pv = v[0];
 pa = (A*)pv;

以下程序使用Cygwin/g++b编译通过:

#include <stdio.h>
#include <vector>

class A
{
public:
 int a;
};
class B
{
public:
 int b;
};
class AB : public B, public A
{
public:
 int ab;
};

int main(int argc, char **argv)
{
 AB *pab = new AB();
 pab->ab = 1;
 pab->b = 2;
 pab->a = 3;

 A* pa = (A*)pab;
 B* pb = (B*)pab;

 printf( "AB: %p\n" \
  " A: %p\n" \
  " B: %p\n",
  pab, pa, pb);

 std::vector<A*> v;
 //implicit type conversion
 v.insert(v.begin(), pab);
 void *pv = v[0];
 pa = (A*)pv;
 printf("pv is %p\npa is %p\npab %s pv\n", pv, pa, (pab == pv) ? "==" : "!=");

 printf("A.a is %d\n", pa->a);
 //forced type conversion
 pv = (void*)pab;
 pa = (A*)pv;
 printf("Now A.a is %d\n", pa->a);
}

运行结果:
AB: 0x6b01f0
A: 0x6b01f4
B: 0x6b01f0
pv is 0x6b01f4
pa is 0x6b01f4
pab != pv
A.a is 3
Now A.a is 2

absurd 发表于2006-07-16 11:48:00  IP: 211.161.63.*
这是编译器的特性,COM里面运用这种特性来取得某个子类实例的偏移量(COM本质论:inttable.h):
#define BASE_OFFSET(ClassName, BaseName) \
(DWORD(static_cast<BaseName*>(reinterpret_cast<ClassName*>(0x10000000))) - 0x10000000)
 
转载自:http://www.yuanma.org/data/2006/0716/article_1143.htm
posted @ 2009-03-30 01:51 江湖飘 阅读(210) 评论(0) 编辑
摘要: 记得有时在刚装完IIS访问localhost网页时会提示输入用户名和密码,我直到现在还没有输入成功过,不知道是否可以通过“我的电脑”中的“管理”菜单中的用户那里设置用户名和密码,然后将相应的用户名和密码输入才会成功,没有试过。另一个解决方法是添加匿名用户访问:IIS属性的“目录安全”页的“编辑”按钮。勾...阅读全文
posted @ 2009-03-29 22:12 江湖飘 阅读(294) 评论(0) 编辑
摘要: 记得刚开始学WCF的时候就尝试过去在IIS中部署部署WCF,但是找了很多网上的资料,都没有部署成功,按照网上的说法是做下来,不知是不是人品的问题,总是成功不了,呵呵。那时候也实在是太菜了,IIS刚接触,甚至连.NET也是刚接触,因为公司用的是直接用SOAP TCP传输的,没有涉及到IIS的部署,所以同事中也都没有试过在IIS中部署,后来就不了了之了。今天因为同住的学长在弄这个东西,然后就帮忙查了一...阅读全文
posted @ 2009-03-29 21:48 江湖飘 阅读(1186) 评论(0) 编辑