How do I call a webservice in the Application_Exit event? - silverlight

How do I call a webservice in the Application_Exit event?
private void Application_Exit(object sender, EventArgs e)
{
TestWSSoapClient.ReleaseUserCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(TestWSSoapClient_ReleaseUserCompleted);
TestWSSoapClient.ReleaseUserAsync(UserToken);
}
The method below is no longer executed.
void TestWSSoapClient_ReleaseUserCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
}
Thank you in advance.

You can't call any web services when exiting by design, however this article might help you with an Javascript alternative.

Do you really need to get the response? You won't be able to get it as all threads will be closed at the end of the Application_Exit function. But if it doesn't matter, you can configure your "ReleaseUser" operation as OneWay.
As I didn't test it, it is only a supposition, but I think it should work (and if it doesn't, well, I will learn something)
Otherwise, as said before, javascript is the only way to go, but it won't work Out of Browser.

Related

Has any one out there in the field used Dispatcher.Yield?

In "Lucian Wischik - Async Part 2 -- deep dive into the new language feature of VB/C#" for NDC 2012, the recommended use of Dispatcher.Yield is introduced to me. Does anyone out there have examples (and explanations) of how (and why) this call is used in the wild?
Well for example if you have a long running task but you still need to update your UI you can use Yield.
Yield gives you the ability to leave the current thread context and allow other code to run in the underlying context.
public async void MyButton_Click(object sender, RoutedEventArgs e)
{
for( int i=0; i < 10000; i++)
{
ProcessSomeStuff(i);
// await the Yield to ensure all waiting messages
// are processed before continuing
await Task.Yield();
}
}
In the example above you can process stuff async but calling Yield will allow events on the UI thread to execute also,
I love to use "await Dispatcher.Yield()" whenever I develop WPF applications.
It is easy to use and barely makes any problems in most cases.
The most useful case using Dispatcher.Yield() is when there is a small time of lag in a operation, which can not be bypassed by "Task", "Thread" etc.
For example, let's say that there is a command button which opens a new window or tab.
private void aButton_Click(object sender, RoutedEventArgs e)
{
// Do some ui stuff
// You can not use Task here at large.
}
What happens here is the whole application stopping, and the button UI remains pressed until the new window or tab opens. It is bad user experience and makes the apllicaiton seem so much slow.
and here is a code with a trick.
private async void aButton_Click(object sender, RoutedEventArgs e)
{
await Dispatcher.Yield();
// Do some ui stuff
}
In here, your code works differently. Dispathcer will process other ui operations first before getting into the job. The button pressed motion will be released first and then a new window will come.
Application stopping will be same, but to users the application will be much smooth and fast. So it is usually a good idea to adopt Dispatcher.Yield() in your application.
In addition, Task.Yield() is different from Dispatcher.Yield(). Try two options and see the results.

Silverlight 5 Domain Model Event Handler being called incrementally

Ok ... next question. I am using Silverlight 5 C# 2012 and have gotten to a point where I could use a little help. I am using the Domain Model to call methods to return information and I discovered that if I hit the same button more than once, the method call happens incrementally. One call for the first click, two calls for the second click, three call for the third, etc.
Please check out the simple code below and if you can provide any insight as to why this is happening, I would greatly appreciate it.
In the Service Layer:
Interface:
[OperationContract]
string GetEnteredString(string strText);
Class:
public string GetEnteredString(string strText)
{
return "You entered: " + strText;
}
In the Silverlight Application:
private void btnGetText_Click(object sender, RoutedEventArgs e)
{
service.GetEnteredStringCompleted += new EventHandler<CARE_WCF.GetEnteredStringCompletedEventArgs>(service_GetEnteredStringCompleted);
service.GetEnteredStringAsync(txtTester.Text);
}
private void service_GetEnteredStringCompleted(object sender, CARE_WCF.GetEnteredStringCompletedEventArgs e)
{
MessageBox.Show(e.Result.ToString());
}
This seems pretty darn straight forward at first glance, but the call to the GetEnteredString method just keeps stacking on top of itself. I think it's because of the += in the Click event but I could be wrong.
Thank you in advance for any insight! I really appreciate it.
Eric
You have to unsubscribe from the event in Completed function like :
service.GetEnteredStringCompleted -= service_GetEnteredStringCompleted;

Is there "LoadComplete" such an event in Windows Forms?

I want my windows form to be loaded first, render its children and all. After that load heavy data in it. This is why I am looking for any event which I could use just after form loading is complete.
Any thoughts on this?
I have never found a better solution than Activated; although that is raised every time the form receives focus - so you need to filter out all the times after the first:
bool _firstActivation = true;
void Form1_Activated(object sender, EventArgs e)
{
if (_firstActivation)
{
_firstActivation = false;
OnFirstActivation();
}
}
private void OnFirstActivation()
{
}
Perhaps you're looking for the Form.Shown event. If you're doing a lot of intensive work though, perhaps you should be using a background thread anyway to avoid locking up the UI.
Like MikeP said you want to handle the Form.Shown event just once. So just attach to the even and detach once done.
private void frmMain_Load(object sender, System.EventArgs e)
{
// Do stuff in form load.
Shown += FirstShown;
}
private void FirstShown(object sender, EventArgs eventArgs)
{
Refresh();
// Do something here
// Detach from this event.
Shown -= FirstShown;
}
I do that in a way that I fire a timer with duration of 1, and kill it in the event, and with that method, I know that message loop will be empty and form initialization will be complete when my event comes.
Event is set up from Form_OnLoad() method.

Silverlight Web Service

Below is the code i used to consume web servcie in SilverLight.
private void button1_Click(object sender, RoutedEventArgs e)
{
BasicHttpBinding bind = new BasicHttpBinding();
EndpointAddress endpoint = new EndpointAddress("http://loalhost/Service.asmx");
ServiceSoapClient client = new ServiceSoapClient(bind, endpoint);
client.RunHelloCompleted += new EventHandler<RunHelloCompletedEventArgs>(client_RunQwinCompleted);
client.RunHelloAsync(command);
}
void client_RunHelloCompleted(object sender, RunHelloCompletedEventArgs e)
{
txtProcess.Text=Process(e.Result);
}
I want to know a way that after i run RunHelloAsync(Command), I want to get the returned result without going to Completed event. Please advise me. thank you.
Simple answer : You can't. Everything in Silverlight is Asynchronous so there is no way to block after the client.RunHelloAsync(command) call and wait for the result.
Long answer : There are ways to simulate working with calls in a synchronous fashion, but the calls still being made asynchronously. Take a look at this thread for a few more answers.

Form Dispose() or Close()

I'm having 2 forms. From one form I created and shown the other form. It's working great. But when I try to close or Dispose that form from the form that created it I get following Exception:
Exception :
Value Dispose() cannot be called while doing CreateHandle().
Stack Trace :
========================
at System.Windows.Forms.Control.Dispose(Boolean disposing)
at System.Windows.Forms.Label.Dispose(Boolean disposing)
at System.ComponentModel.Component.Dispose()
at System.Windows.Forms.Control.Dispose(Boolean disposing)
at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
at System.Windows.Forms.Form.Dispose(Boolean disposing)
at Speedometer_Application.frmSpeedometer.Dispose(Boolean disposing)
Any idea????
The error Value Close() cannot be called while doing CreateHandle() usually happens when we try to close the form in the constructor or Load event.
For example, the following code gives the error:
private void frmCustomer_Load(object sender, EventArgs e)
{
if (!Valid())
this.Close;
}
The Solution:
private void frmCustomer_Load(object sender, EventArgs e)
{
if (!Valid())
this.BeginInvoke(new MethodInvoker(Close));
}
You can use this in your code.
it is hard to say what is the problem from the code you posted.
The code that you posted should work (form shown with Show() should be possible to close with Dispose() method).
The reason why it does not work is probably somewhere in the form that you are trying to dispose of. When you call Dispose() method (according to the error message this is what happens) on an object, that object will try to dispose of all its children and do some cleanup. That is the place to look for error.
My suggestion is to comment out all your code in the form objfrm (or make new EMPTY form) and see if error happens. It should not happen. Then start adding commented code and see when the error happens. I bet it will be in the code that is being called as consequence of Dispose method.
The code is as follows:
if (frmMain.objfrm== null)
{
frmMain.objfrm = frmMyForm.Instance;
frmMain.objfrm.ShowInTaskbar = false;
}
frmMain.objfrm.Show();
frmMain.objfrm.BringToFront();
frmMain is the Main Form that has a static variable of the frmMyForm. than in my code whereever i want to use this I just check if it's not null than create it using a static Instance and than give the peoperty.
While closing the form I have the following code:
frmMain.objfrm.Close_this();
The Close_this calls the Close() or Dispose() method.
But when I call that function I get the above exception.
You need to use ShowDialog instead of Show thats the problem. Show dont block the application and the code keeps running.
You are disposing the object when the GUI is creating it (that what the exception said)
Try with this:
if (frmMain.objfrm== null)
{
frmMain.objfrm = frmMyForm.Instance;
frmMain.objfrm.ShowInTaskbar = false;
}
frmMain.objfrm.ShowDialog();
Note the ShowDialog()

Resources