Best practice for webservices - web-services

I've created a webservice and when I want to use its methods I instantiate it in the a procedure, call the method, and I finally I dispose it, however I think also it could be okay to instantiate the webservice in the "private void Main_Load(object sender, EventArgs e)" event.
The thing is that if I do it the first way I have to instantiate the webservice every time I need one of its methods but in the other way I have to keep a webservice connected all the time when I use it in a form for example.
I would like to know which of these practices are better or if there's a much better way to do it
Strategy 1
private void btnRead_Click(object sender, EventArgs e)
{
try
{
//Show clock
this.picResult.Image = new Bitmap(pathWait);
Application.DoEvents();
//Connect to webservice
svc = new ForPocketPC.ServiceForPocketPC();
svc.Credentials = new System.Net.NetworkCredential(Settings.UserName, Settings.Password);
svc.AllowAutoRedirect = false;
svc.UserAgent = Settings.UserAgent;
svc.PreAuthenticate = true;
svc.Url = Settings.Url;
svc.Timeout = System.Threading.Timeout.Infinite;
svc.CallMethod();
...
}
catch (Exception ex)
{
ShowError(ex);
}
finally
{
if (svc != null)
svc.Dispose();
}
}
Strategy 2
private myWebservice svc;
private void Main_Load(object sender, EventArgs e)
{
//Connect to webservice
svc = new ForPocketPC.ServiceForPocketPC();
svc.Credentials = new System.Net.NetworkCredential(Settings.UserName, Settings.Password);
svc.AllowAutoRedirect = false;
svc.UserAgent = Settings.UserAgent;
svc.PreAuthenticate = true;
svc.Url = Settings.Url;
svc.Timeout = System.Threading.Timeout.Infinite;
}
private void btnRead_Click(object sender, EventArgs e)
{
try
{
//Show clock
this.picResult.Image = new Bitmap(pathWait);
Application.DoEvents();
svc.CallMethod();
...
}
catch (Exception ex)
{
ShowError(ex);
}
}
private void Main_Closing(object sender, CancelEventArgs e)
{
svc.Dispose();
}

It depends on how often you are going to be calling the web service. If you're going to be calling it almost constantly, it would probably be better to use method #2. However, if it's not going to be getting called quite so often, you are better off using method #1, and only instantiating it when you need it.

Right now I made a solution for a mobile device and it turns to be used on irregular times, it could be used in 10 minutes, 1 hour, 4 hours its very variable, it seems that the better aproach is the first strategy.
Last year we went on a project where we used webservices, the fact is that we instantiated our webservices at the Sub New() procedure and it run it very well, however, sometimes some users claimed at us that they woke up from their chairs and when they returned and tried to continue on the application they received a timeout error message and they had to re-login again.
We thougth that maybe that was Ok because maybe the users went out for a very long time out of their seats, but once in a presentation of the application with the CEOs it happened exactly the same scenario and personally I didn't like that behaviour and that's why the question.
Thanks for the answer.

Related

UWP - Platform::DisconnectedException while navigating between pages

I've got the following setup: A MainPage xaml-view and a SettingPage xaml-view. In the SettingPage xaml-view I activated the back button which is in the window title bar and I added a BackRequestedEventArgs. (Furthermore I have a DX12 xaml page but it is not involved to the navigation yet, so it will never get initialized.)
So my problem is: if I click on a flyoutitem called settings which is located in the MainPage, I'll get navigated to the SettingPage. The backbutton appears in the titlebar and if I click it, I get back to the MainPage. Now I do it once again: clicking on settings, navigating to SettingPage. Now if I click on the backbutton OR close the window the app crashes and shows me the following exception:
Platform::DisconnectedException ^ at 0x046BED80. HRESULT:0x80010108
My Question: How do I fix it?
Here is my Code for it:
MainPage Navigation:
void MainPage::MenuFlyoutItemSettings_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid));
}
SettingsPage:
// in Constructor
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->AppViewBackButtonVisibility = Windows::UI::Core::AppViewBackButtonVisibility::Visible;
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &SettingsPage::App_BackRequested);
void SettingsPage::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
if (rootFrame == nullptr)
return;
// Navigate back if possible, and if the event has not
// already been handled.
if (rootFrame->CanGoBack && e->Handled == false)
{
e->Handled = true;
rootFrame->GoBack();
}
}
Furthermore both methods have onSuspending and onResuming handlers added by me manually, but they are both empty:
//in constructor
Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending);
Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming);
void SettingsPage::OnSuspending(Object^ sender, SuspendingEventArgs^ e) {
}
void SettingsPage::OnResuming(Object^ sender, Object^ e) {
}
NOTE: If I delete the whole backbutton-code, the app never crashes with this exception, so I think it is an error in this code.
EDIT 2017-09-04:
After working on Sunteen Wu - MSFT's Answer from below I realised that even If I delete all the backbutton-code I will get this exception as soon as I enter the SettingsPage the first time and close the app. So here is my current scenario where I am getting the described exception:
The only code I've got now for navigation:
MainPage (in a custom settingsbutton):
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid));
SettingsPage (in a custom backbutton):
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid));
So after the first time I navigate to the settingspage by pressing the settingsbutton I get the described exception only if I shutdown the app (same if clicking on red x or stopping debugger). The navigation works fine though, I can swap between the pages as long as I want and I won't get the exception while running the app.
FINAL ANSWER 2017-09-06:
Combining Sunteen Wu - MSFT's Answer with deleting the above mentioned
Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending);
Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming);
handlers is the solution for me. Now there is no Disconnectedexception and the Back-Button-Logic is also working!
Platform::DisconnectedException ^ at 0x046BED80. HRESULT:0x80010108
Actually you are meeting the cycles issue. For what it the cycles issue and how to resolve please reference Weak references and breaking cycles (C++/CX). You met the cycles issue when you subscribe the BackRequested event handle. With the WeakReference you will find the issue:
WeakReference wr(this);
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>([wr](
Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e)
{
SettingsPage^ c = wr.Resolve<SettingsPage>();
if (c != nullptr)
{
Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
if (rootFrame == nullptr)
return;
if (rootFrame->CanGoBack && e->Handled == false)
{
e->Handled = true;
rootFrame->GoBack();
}
}
else
{
throw ref new DisconnectedException();
}
});
From the article, when an event handler throws DisconnectedException, it causes the event to remove the handler from the subscriber list. So that to resolve it, you can remove the event handle from subscriber list after back requested. The following code snippet showed how to remove.
Windows::Foundation::EventRegistrationToken cookie;
SettingsPage::SettingsPage()
{
InitializeComponent();
...
cookie = Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &SettingsPage::App_BackRequested);
}
void SettingsPage::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
...
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested -= cookie;
}
Additionally, I recommend you subscribe this event inside App.xaml.cpp to avoid this issue. You can subscribe it inside OnLaunched like follows:
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
...
}
else
{
...
}
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &App::App_BackRequested);
}
void App::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
...
}
More details you can reference BackButton official sample.

C++ UI Invoke not Working

When debugging,I found my program have stopped after
myServer->Invoke(myServer->myShowMessage);
I tried to find where it goes,and I set several breaks but I didn't find where it was going.However,I also set a break on ShowMessageMethod where it should go but I am sure it wasn't going to there.It was just look like dealing with other things and trapping in it.I suspect there was something wrong with the UI thread,but I have little knowledge about the underlying in Windows Message. I have create some other threads in main thread, is that makes things all different? I just followed the Invoke method code on msdn. And Here are my codes:
Server::Server(){
InitializeComponent();
myShowMessage = gcnew ShowMessageDelegate(this,&Server::ShowMessageMethod);
}
System::Void Server::start_Click(System::Object^ sender, System::EventArgs^ e){
Thread^ myThread = gcnew Thread(gcnew ThreadStart(this,&Server::ListenThreadFunc));
myThread->Start();
}
void Server::ShowMessageMethod(){
String^ message = "Get Successful";
this->APTBX->AppendText(message);
}
void Server::ListenThreadFunc(){
ServerListen^ mySL = gcnew ServerListen(this);
mySL->ListenThread();
}
ServerListen::ServerListen(Server^ _s){
myServer = _s;
}
void ServerListen::ListenThread(){
array<Object^>^myStringArray = { convert.toStringDelegate(information) };
Object^ re = myServer->Invoke(myServer->myShowMessage);
}
thanks in advance.

How to close the card by itself after executed a HTTP request?

I have an app with contextual commands. After triggered a contextual command, it will make a HTTP request with a link and post the result on the card, something like, "Completed!". I want this card to be closed by itself after one second so that the user need not to tap to close it. Once the result card is closed, it will go back to contextual command lists with "Ok, glass" at footer and ready for next command.
May i know how to do that?
private class HTTPRequest extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
try {
if (mWhat.equalsIgnoreCase("GET")) {
// get json via YouTube API
URL url = new URL("http://example.com");
mUrlConnection = (HttpURLConnection)
url.openConnection();
InputStream in = new BufferedInputStream(
mUrlConnection.getInputStream());
int ch;
StringBuffer b = new StringBuffer();
while ((ch = in.read()) != -1) {
b.append((char) ch);
}
mResult = new String(b);
}
} catch (Exception e) {}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mTvInfo.setText(mResult);
}
You can use an Android Dialog for this:
Use CardBuilder to create the "Completed" card using the MENU layout.
Create a new instance of Dialog and set its content view to be the view returned by CardBuilder.getView.
Show the dialog.
Use Handler.postDelayed (or some similar mechanism) to automatically dismiss the dialog after the desired amount of time has passed.

How to implement auto save functionality in silverlight

I want to implement auto save functionality.
I have a silverlight application, in which, we are sending data on server on clicking of a button. Now i don't want to click on that button, i want, my data should be post to server periodically with time interval of 20 or 30 seconds.
Plz provide me your valuable suggestion to how to implement this
I use this code to keep a session alive. It does the same thing that you are trying to do; automatically calls a service after specified regular intervals:
public Page()
{
InitializeComponent();
// Set up timer
System.Windows.Threading.DispatcherTimer dt =
new System.Windows.Threading.DispatcherTimer();
// Set to call every 5 minutes
dt.Interval = new TimeSpan(0, 0, 5, 0, 0);
// Set up event handler
dt.Tick += new EventHandler(dt_Tick);
// Start timer
dt.Start();
}
void dt_Tick(object sender, EventArgs e)
{
// Call web service
Ping();
}
void Ping()
{
WebTest.otsref.SilverlightServiceClient webService = new WebTest.SilverlightServiceClient();
webService.PingAsync();
}

Rhino Mocks, MbUnit: Best way to check if object has raised an event

I have an object that I'm testing that raises an event. What is the best way of using Rhino Mocks to check that it was raised?
Best I could come up with (I am certain it gets better than this):
public void MyCallback(object sender, EventArgs e) { _flag = true;}
[Test]
public void DoSomethingRaisesEvent() {
_flag = false;
using(_mocks.Record()) {
Expect.Call(delegeate { _obj.DoSomething();});
}
using(_mocks.Playback()) {
_obj = new SomethingDoer();
_obj.SomethingWasDoneEvent += new EventHandler(MyHandler);
Assert.IsTrue(_flag);
}
}
I found this article by Phil Haack on how to test events using anonymous delegates
Here is the code, ripped directly from his blog for those too lazy to click through:
[Test]
public void SettingValueRaisesEvent()
{
bool eventRaised = false;
Parameter param = new Parameter("num", "int", "1");
param.ValueChanged +=
delegate(object sender, ValueChangedEventArgs e)
{
Assert.AreEqual("42", e.NewValue);
Assert.AreEqual("1", e.OldValue);
Assert.AreEqual("num", e.ParameterName);
eventRaised = true;
};
param.Value = "42"; //should fire event.
Assert.IsTrue(eventRaised, "Event was not raised");
}
I'm not sure how your test actually calls the DoSomething() Method. Maybe you're missing something to fire the event. Other than that, I think you have are on the right track for testing events with Rhino Mocks
In any case, here is another way I like to deal with events:
[Test]
public void MyEventTest()
{
IEventRaiser eventRaiser;
mockView = _mocks.CreateMock<IView>();
using (_mocks.Record())
{
mockView.DoSomethingEvent += null;
eventRaiser = LastCall.IgnoreArguments();
}
using (_mocks.Playback())
{
new Controller(mockView, mockModel);
eventRaiser.Raise(mockView, EventArgs.Empty);
}
}