XBAP page unload

  • Thread starter Thread starter Steven Tang
  • Start date Start date
S

Steven Tang

It seems that one page XBAP whose Unloaded event
never get called, I need put some clearing stuff (I.G stop dispatcher time)
when
user close browser, it unload event doesn't work, where
shall I put?
 
Hello Steven Tang,

Thanks for using Microsoft Newsgroup Support Service, my name is Ji Zhou
[MSFT] and I will be working on this issue with you.

I have a quick test on my side as follows, and can reproduce the issue when
I directly close the web browser.

In the .xaml file,
<Page x:Class="WpfBrowserApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1" Unloaded="Page_Unloaded">
<Grid>
</Grid>
</Page>

In the Page1.xaml.cs,
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Test");
}

But when I press F5 to refresh the XBAP page, the Page's unload event fires
correctly. That is to say, this event will only fires when the embedded wpf
page gets unloaded and the Web Browser remains open. In my opinion, when
we close the web browser directly, the whole XBAP application will shut
down and the resource will be cleaned up automatically. I think it is not
necessary to stop the dispatcher timer there? Could you please clarify what
exactly you want to do in the Unload event handle? So that we can try to
provide a future suggestion on an specific scenario.

And based on my research on the web, I found the following discussion in
the MSDN WPF Forum. We can see that another two possible workarounds will
be Application.Exit and the IProvideCustomContentState. Codes in these
event handler or function are guarantee to be called.
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e034f5f5-43ca-4b1c-
9b54-d74b727f8e12/

Please let me know if these suggestions fit your scenario.

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/default.aspx?target=assistance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Mr Zhou,
Thanks for response, actually I tried the Application.Exit and it
didn't work,
IProvideCustomContentState doesn't work either.
My concern to this issue is that
1. When I close the browser, there will be a PresentationHost.exe
corpse
left in the Task Manager every time when I run the XBAP, If I run multiple
time,
multiple PresentationHost.exe in the Task Manager, they will not release the
resource.
2. My XBAP load one dll and the dll do sth. I have an 1s timer in
the XBAP to check the background status, I added the unload dll code in the
AppEXit methods we mentioned, and I debugged into the code, after traced
through the AppExit code, the application will go back to the timer handler
and this cause that even I closed the browser, there still be an corp left @
task manager until I manually kill it from task manager.
3. If I could know the event of the page closed, I can stop the
timer first so that the process will not go back to xbap code and this shall
be able to fix the corpse issue.
4. Any other event indicates that browser is closing?

Best Regards
--
=======================
Steven Tang
SYWWUYU)
**:)


""Ji Zhou [MSFT]"" said:
Hello Steven Tang,

Thanks for using Microsoft Newsgroup Support Service, my name is Ji Zhou
[MSFT] and I will be working on this issue with you.

I have a quick test on my side as follows, and can reproduce the issue when
I directly close the web browser.

In the .xaml file,
<Page x:Class="WpfBrowserApplication1.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1" Unloaded="Page_Unloaded">
<Grid>
</Grid>
</Page>

In the Page1.xaml.cs,
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("Test");
}

But when I press F5 to refresh the XBAP page, the Page's unload event fires
correctly. That is to say, this event will only fires when the embedded wpf
page gets unloaded and the Web Browser remains open. In my opinion, when
we close the web browser directly, the whole XBAP application will shut
down and the resource will be cleaned up automatically. I think it is not
necessary to stop the dispatcher timer there? Could you please clarify what
exactly you want to do in the Unload event handle? So that we can try to
provide a future suggestion on an specific scenario.

And based on my research on the web, I found the following discussion in
the MSDN WPF Forum. We can see that another two possible workarounds will
be Application.Exit and the IProvideCustomContentState. Codes in these
event handler or function are guarantee to be called.
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e034f5f5-43ca-4b1c-
9b54-d74b727f8e12/

Please let me know if these suggestions fit your scenario.

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/default.aspx?target=assistance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Dear Mr. Tang,

Thanks very much for the detailed information. But as far as I know, the
Application.Exit is the only reliable event that fires when we close the
web browser directly. And from my current research, the issue may not be
related to the dispatcher timer. Detail goes as follows,

I am trying to reproduce the issue but still cannot in my side. Currently,
I am using the following codes to simulate your described scenario. It
firstly creates a new AppDomain and from that AppDomain, I set a 1s
dispatcher timer. As you said, I can also see that after the codes returns
from the Application.Exit event handle, it goes into the dispatcher timer's
Tick event handle immediately. But after that, both of the IExplorer.exe
and the PresentationHost.exe process quit correctly. I did not see the
PresentationHost.exe remain in the memory in my side. Consequently, I think
the issue may cause from other parts of codes. It will not be fixed even we
stop the dispatcher timer.

public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}

void Current_Exit(object sender, ExitEventArgs e)
{
Debug.Print("Application Exited");
}

private void Page_Loaded(object sender, RoutedEventArgs e)
{
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase =
AppDomain.CurrentDomain.BaseDirectory;

Application.Current.Exit += new ExitEventHandler(Current_Exit);
AppDomain newDomain = AppDomain.CreateDomain("NewDomain", null,
domaininfo);
MarshalByRefType mbrt =
newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,
"WpfBrowserApplication1.MarshalByRefType") as MarshalByRefType;
mbrt.SetTimer();
}
}

public class MarshalByRefType : MarshalByRefObject
{
public void SetTimer()
{
System.Windows.Threading.DispatcherTimer timer = new
System.Windows.Threading.DispatcherTimer();
timer.IsEnabled = true;
timer.Interval = new TimeSpan(0, 0, 1);
timer.Tick += new EventHandler(timer_Tick);
}

void timer_Tick(object sender, EventArgs e)
{
Debug.Print("Timer Ticked");
}
}

For future investigation into this issue, I firstly need to reproduce it in
my side. Thus, would you like to share a mini project that can show the
problem? You can send it to me at this email address, (e-mail address removed).
Thanks for your cooperation and have a nice day, Steven!

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Mr.Zhou,
Sorry that I didn't response for couple days due to that I was busy on
other stuff, and thanks a lot that you spent time on recreating the cases.
I tried to debug into my code, after I close the browser, to code will
go to
AppExit, and after the AppExit, the code will go to timer handler, if I
disable
all the break ponters and press the continue, after I close the browser, the
debug will not stop and nothing shows on Call Stack, and I clicked on the
break all, the call stack will be:
ntdll.dll!KiFastSystemCallRet()
[Frames below may be incorrect and/or missing, no symbols loaded for
ntdll.dll]
ntdll.dll!NtWaitForMultipleObjects() + 0xc bytes
user32.dll!TranslateMessageEx() + 0x172 bytes
ole32.dll!CoGetPSClsid() + 0x154 bytes
ole32.dll!CoGetPSClsid() + 0x2b4 bytes
ole32.dll!WdtpInterfacePointer_UserUnmarshal() + 0x1c6 bytes
ole32.dll!WdtpInterfacePointer_UserUnmarshal() + 0x11bb bytes
ole32.dll!WdtpInterfacePointer_UserUnmarshal() + 0x1027 bytes
ole32.dll!CoGetPSClsid() + 0x35a bytes
ole32.dll!CoGetPSClsid() + 0x30c bytes
ole32.dll!CoRegisterSurrogateEx() + 0x3b9c bytes
rpcrt4.dll!NdrProxySendReceive() + 0x43 bytes
rpcrt4.dll!NdrProxySendReceive() + 0xa4 bytes
rpcrt4.dll!NdrClientCall2() + 0x764 bytes
rpcrt4.dll!I_RpcGetBufferWithObject() + 0xb7 bytes
ole32.dll!ReadClassStm() + 0xdad bytes
ole32.dll!ReadClassStm() + 0xd5f bytes
ole32.dll!CoRegisterSurrogateEx() + 0x2a43 bytes
ole32.dll!CoRegisterSurrogateEx() + 0x291a bytes
ole32.dll!CoRegisterSurrogateEx() + 0x27c1 bytes
ole32.dll!CoRegisterSurrogateEx() + 0x272b bytes
ole32.dll!CoRegisterSurrogateEx() + 0x2678 bytes
rpcrt4.dll!IUnknown_Release_Proxy() + 0x13 bytes
PresentationHostDLL.dll!CreateIDispatchSTAForwarder() + 0x1cd6 bytes
and I clicked on the continue again, the code will keep going and just
won't get out. The only way I to stop the debugging session is to hit the
Stop Debugging button.
According your experience, if the XBAP will not clear
PresentationHost.exe
after closed the browser, and the PageUnload could not be called, how to fix
this
issue?

Best Regards

--
=======================
Steven Tang
SYWWUYU)
**:)


""Ji Zhou [MSFT]"" said:
Dear Mr. Tang,

Thanks very much for the detailed information. But as far as I know, the
Application.Exit is the only reliable event that fires when we close the
web browser directly. And from my current research, the issue may not be
related to the dispatcher timer. Detail goes as follows,

I am trying to reproduce the issue but still cannot in my side. Currently,
I am using the following codes to simulate your described scenario. It
firstly creates a new AppDomain and from that AppDomain, I set a 1s
dispatcher timer. As you said, I can also see that after the codes returns
from the Application.Exit event handle, it goes into the dispatcher timer's
Tick event handle immediately. But after that, both of the IExplorer.exe
and the PresentationHost.exe process quit correctly. I did not see the
PresentationHost.exe remain in the memory in my side. Consequently, I think
the issue may cause from other parts of codes. It will not be fixed even we
stop the dispatcher timer.

public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}

void Current_Exit(object sender, ExitEventArgs e)
{
Debug.Print("Application Exited");
}

private void Page_Loaded(object sender, RoutedEventArgs e)
{
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase =
AppDomain.CurrentDomain.BaseDirectory;

Application.Current.Exit += new ExitEventHandler(Current_Exit);
AppDomain newDomain = AppDomain.CreateDomain("NewDomain", null,
domaininfo);
MarshalByRefType mbrt =
newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,
"WpfBrowserApplication1.MarshalByRefType") as MarshalByRefType;
mbrt.SetTimer();
}
}

public class MarshalByRefType : MarshalByRefObject
{
public void SetTimer()
{
System.Windows.Threading.DispatcherTimer timer = new
System.Windows.Threading.DispatcherTimer();
timer.IsEnabled = true;
timer.Interval = new TimeSpan(0, 0, 1);
timer.Tick += new EventHandler(timer_Tick);
}

void timer_Tick(object sender, EventArgs e)
{
Debug.Print("Timer Ticked");
}
}

For future investigation into this issue, I firstly need to reproduce it in
my side. Thus, would you like to share a mini project that can show the
problem? You can send it to me at this email address, (e-mail address removed).
Thanks for your cooperation and have a nice day, Steven!

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Mr. Tang,

To do future investigation, I firstly need to reproduce the issue in my
side. It is really hard to guess the problem without seeing your other
parts of codes. Would you mind sending me a mini reproducible project, or
posting the codes in your timer tick event here? Thanks for your
understanding.

Have a good day!

Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top