I've developed a simple Web Service and a Windows Phone 8 app to consume it.
Everything works as intended but the way my current (working) code stands, it's assuming the Web Service to always be running and available. Seeing as that may not always be the case, I'd like to try and add some kind of connectivity testing before I start sending requests. I've read that there's no straightforward way of being certain that the WS is up and running other than querying it somehow.
With that in mind, here's what my LoadData method structure looks like (Feb. 26th):
public void LoadData(string articleCode = null)
{
try
{
this.ArticleItems.Clear();
MyServiceSoapClient ws = new MyServiceSoapClient();
CheckWebService();
if (this.isWebServiceUp)
{
if (!String.IsNullOrEmpty(articleCode))
{
ws.GetBasicDataAsync(articleCode);
ws.GetBasicDataCompleted += Ws_GetBasicDataCompleted;
//(irrelevant code supressed for clarity)
this.IsDataLoaded = true;
}
}
else
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = "Could not connect to Web Service." });
ws.Abort();
}
}
}
And it still throws an unhandled CommunicationException error.
EDIT: After taking into consideration both suggestions and doing some searching, I've tried to set up a "heartbeat"-type method but it's not working correctly. Asynchronous programming is a relatively new paradigm for me so I most likely am missing something but here goes my attempt at an implementation thus far (getting a "Unable to cast object of type 'System.Net.Browser.OHWRAsyncResult' to type 'System.Net.HttpWebResponse'" exception):
public void CheckWebService()
{
try
{
Uri wsURL = new Uri("http://localhost:60621/WebService1.asmx");
//try accessing the web service directly via its URL
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(wsURL);
request.Method = "HEAD";
//next line throws: "Unable to cast object of type 'System.Net.Browser.OHWRAsyncResult' to type 'System.Net.HttpWebResponse'."
using (var response = (System.Net.HttpWebResponse)request.BeginGetResponse(new AsyncCallback(ServiceCallback), request))
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
throw new Exception("Error locating web service");
}
}
}
catch (System.ServiceModel.FaultException fe)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = fe.Message });
}
catch (System.ServiceModel.CommunicationException ce)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = ce.Message });
}
catch (System.Net.WebException we)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = we.Message });
}
catch (Exception ex)
{
this.ArticleItems.Add(new ItemViewModel() { LineOne = ex.Message });
}
}
private void ServiceCallback(IAsyncResult asyncResult)
{
try
{
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)asyncResult.AsyncState;
using (var response = (System.Net.HttpWebResponse)request.EndGetResponse(asyncResult))
{
if (response != null && response.StatusCode == System.Net.HttpStatusCode.OK)
{
this.isWebServiceUp = true;
request.Abort();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
Related
I am developing an web services in mvc asp.net 5.
I am using a SDK from a dll, but when I call a function from this dll it does not respond. It stays waiting an does not throw an error.
I am compiling in x86. This is the code
public Respuesta TimbrarFactura(String ConceptoDocumento, String Serie, double Folio, String password)
{
try
{
int resp = SDK.fEmitirDocumento(ConceptoDocumento, Serie, Folio, password, "");
if (resp == 0)
{
return new Respuesta(true, "Se timbro el documento");
}
else
{
try
{
SDK.fError(resp, sMensaje, 255);
}
catch(Exception e)
{
}
return new Respuesta(false, sMensaje.ToString());
}
}catch(Exception ex)
{
return null;
}
}
I added a try catch block to get some error, but the catch block is never entered. What could be causing this?
This is killing me. I'm new to android/Xamarin. I can't find anything on the web that explains what is going on here.
I'm using xamarin forms for my application. I have a page that synchronizes the device with a web service.
The method simply retrieves 100 records at a time from the web service and updates a sqlite table on the device. I randomly get this error. I'm running 5000 records for my test sample.
Here is the button click:
public async void OnSyncCachedData_Clicked(object sender, EventArgs e)
{
activityIndicatorAll.IsRunning = true;
try
{
actIndSyncItems.IsRunning = true;
SyncAllFinished += SynchAllFinishedProcessing;
await Task.Run(async () => await App.ItemsRepo.LoadCacheDataFromCacheAsync(DbPath).ConfigureAwait(false));
}
catch (BAL.Exceptions.NetworkException nex)
{
await DisplayAlert(Messages.TitleError, nex.Message, Messages.MsgOk);
}
catch (Exception ex)
{
await DisplayAlert(Messages.TitleError, string.Format(Messages.MsgAreYouConnectedParm1, ex.Message), Messages.MsgOk);
}
finally
{
EventHandler handler = SyncAllFinished;
if (handler != null)
{
handler(this, new EventArgs());
}
SyncAllFinished -= SynchAllFinishedProcessing;
}
}
the main worker method:
public async Task<bool> LoadCacheDataFromCacheAsync(string dbPath)
{
WebSvcManagers.ItemsManager itemsWebServiceManager = new WebSvcManagers.ItemsManager();
List<Models.WebServiceItems> consumedRecords = new List<Models.WebServiceItems>() { };
int bufferSize = 100;
Log.Debug(TAG, "LoadCacheDataFromCacheAsync starting");
try
{
{
int lastID = 0;
IEnumerable<Models.WebServiceItems> remoteRecords = await BAL.DataAccessHelper.GetItemsFromGPCacheAsync(App.Login, lastID, bufferSize, itemsWebServiceManager).ConfigureAwait(false);
while (remoteRecords.Count() != 0)
{
foreach (Models.WebServiceItems remoteItem in remoteRecords)
{
// DbActionTypes dbAction = (DbActionTypes)remoteItem.DbAction;
Models.Items itemRecord = new Models.Items() { ItemNumber = remoteItem.ItemNumber.ToUpper().Trim(), Description = remoteItem.Description.Trim() };
Log.Debug(TAG, "Processing {0}", remoteItem.ItemNumber.Trim());
bool success = await AddRecordAsync(itemRecord).ConfigureAwait(false);
if (success)
consumedRecords.Add(remoteItem);
}
lastID = remoteRecords.Max(r => r.RecordID) + 1;
remoteRecords = await BAL.DataAccessHelper.GetItemsFromGPCacheAsync(App.Login, lastID, bufferSize, itemsWebServiceManager).ConfigureAwait(false);
}
}
// await UpdateConsumedRecords(consumedRecords).ConfigureAwait(false);
return true;
}
catch (Exception ex)
{
this.StatusMessage = ex.Message;
Log.Debug(TAG, "Error Catch: {0}", StatusMessage);
return false;
}
finally
{
itemsWebServiceManager = null;
HandleSyncFinished(this, new EventArgs());
SyncAllFinished -= HandleSyncFinished;
}
}
My simple webservice manager:
public static async Task<IEnumerable<Models.WebServiceItems>> GetItemsFromGPCacheAsync(Models.Login login, int offset, int bufferCount, WebSvcManagers.ItemsManager manager)
{
try
{
return await manager.GetCacheRecordsAsync(login, offset, bufferCount).ConfigureAwait(false);
}
catch (Exception)
{
throw;
}
}
And the code for the interaction with the web service:
const int bufferSize = 100;
public async Task<IEnumerable<Models.WebServiceItems>> GetCacheRecordsAsync(Models.Login login, int offSet, int bufferCount)
{
string deviceID = App.ConfigSettings.DeviceID.ToString("D");
try
{
///* Testing start */
//return await DataStore(bufferCount, offSet).ConfigureAwait(false);
///* Testing end */
if (!App.IsConnected)
throw new BAL.Exceptions.NetworkException(Messages.ExceptionNetworkConnection);
string user = login.UserName;
string password = login.Password;
HttpClient client = HttpClientExtensions.CreateHttpClient(user, password);
try
{
List<Models.WebServiceItems> items = new List<Models.WebServiceItems>() { };
int lastID = offSet;
int i = 0;
string uri = string.Format("{0}", string.Format(Messages.WebRequestItemsCacheParms3, deviceID, lastID, Math.Min(bufferCount, bufferSize)));
Log.Debug(TAG, string.Format("Webservice {0}", uri));
string response = await client.GetStringAsync(uri).ConfigureAwait(false);
while (i < bufferCount && response != null && response != "[]")
{
while (response != null && response != "[]")
{
dynamic array = JsonConvert.DeserializeObject(response);
foreach (var item in array)
{
i++;
items.Add(new Models.WebServiceItems()
{
ItemNumber = item["ITEMNMBR"].Value.Trim(),
Description = item["ITEMDESC"].Value.Trim(),
DbAction = (int)(item["DbAction"].Value),
RecordID = (int)(item["DEX_ROW_ID"].Value),
});
lastID = (int)(item["DEX_ROW_ID"].Value);
Log.Debug(TAG, string.Format("Webservice {0}", item["ITEMNMBR"].Value.Trim()));
}
if (i < Math.Min(bufferCount, bufferSize))
{
uri = string.Format("{0}", string.Format(Messages.WebRequestItemsCacheParms3, deviceID, lastID + 1, Math.Min(bufferCount, bufferSize)));
Log.Debug(TAG, string.Format("Webservice {0}", uri));
response = await client.GetStringAsync(uri).ConfigureAwait(false);
}
else
break;
}
}
Log.Debug(TAG, string.Format("Webservice return {0} items", items.Count()));
return items;
}
catch (Exception ex)
{
Log.Debug(TAG, "Error Catch: {0}", ex.Message);
throw ex;
}
}
catch (System.Net.Http.HttpRequestException nex)
{
throw new Exception(string.Format(Messages.ExceptionWebServiceLoginParm1, nex.Message));
}
catch (Exception)
{
throw;
}
}
I've had assistance from a Xamarin instructor and we thought we got it, (because this is random), but it clearly is not swatted. I've been hitting my head up against a wall for over 3 weeks on this. It smells like a memory leak, but I have no idea how to find it with such a generic error message that doesn't appear on web searches.
Somebody out there with some major brains, Please help!
Error:
08-03 12:41:11.281 D/X:ItemsRepositiory(16980): UpdateRecordAsync 65702-40710
08-03 12:41:11.306 D/X:ItemsManager(16980): Webservice DeleteCacheRecordAsync 20497
08-03 12:41:11.406 D/X:ItemsManager(16980): Webservice api/InventoryItems?DeviceID=7c5bb45d-2ea0-45b9-ae50-92f2e25a2983&OffSet=20498&Max=100&cached=true
Thread finished: <Thread Pool> #7 08-03 12:41:11.521 E/art (16980): Nested signal detected - original signal being reported The thread 'Unknown' (0x7) has exited with code 0 (0x0).
This might be a problem with the VS Android Emulator. As we have shown in tests, this is not reproducible on the Google Android Emulators, nor on Xamarin Android Player, nor on a physical Android device.
I am currently using this somewhat tedious pattern to generate error message for user running some long operation:
string _problem;
void SomeLongRunningMethod()
{
try
{
_problem = "Method1 had problem";
Method1();
_problem = "Unexpected error during doing something in Method2";
if(Method2())
{
_problem = "Method3 fails";
Method3();
}
_problem = "Not possible to obtain data";
var somedata = Method4();
}
catch(Exception)
{
MessageBox.Show("Problem with some long running method: " + _problem);
}
}
Either of methods may throw and I want to tell the user at which step failure occurs. This is done by setting _problem before running any of them.
In some cases I can use different Exception types to catch, but that doesn't works always, e.g. both Method1 and Method2 can throw InvalidOperationException().
This repeated code looks like a pattern. Though I can't recognize it. Any ideas? How to improve readability?
You could use when in the catch to differentiate between the same exception types and to check which method threw this exception:
void SomeLongRunningMethod()
{
try
{
Method1();
if (Method2())
{
Method3();
}
var somedata = Method4();
}
catch (InvalidOperationException invEx) when (invEx.TargetSite?.Name == nameof(Method1))
{
// ...
}
catch (InvalidOperationException invEx) when (invEx.TargetSite?.Name == nameof(Method2))
{
// ...
}
catch (Exception ex)
{
// ...
}
}
You could get the method that caused the exception using error.TargetSite. The only thing you need to change is your catch line: catch (Exception error)
I'd make a sequence of the things you want to do and run through them:
var methodList = new[]{
new{action = (Action)Method1, identifier = "Method1"},
new{action = (Action)Method2, identifier = "Method2"},
new{action = (Action)Method3, identifier = "Method3"},
};
string problem = null;
foreach(var info in methodList)
{
try
{
info.action();
}
catch(InvalidOperationException)
{
problem = string.Format("{0} failed", info.identifier);
break;
}
}
if(problem != null)
{
//notify
}
I have a recursive function in a windows service. This function upon completion rewinds itself as it has been repeated multiple times in recursion. Isn't that an overhead ?
Is there any way to avoid unwinding ? Is there any better approach?
Edit : In this method, I get 100 records from DB and then process them and then get another 100 and so on till all the records in DB have been processed.
Also, there is no limit of how many total records there might be in the db so this function can repeat itself quite a lot.
public void ServiceFunctionality()
{
try
{
// Get Data From WEBAPI
HttpClient client = new HttpClient();
HttpResponseMessage response = response = client.GetAsync("webapi url link").Result;
Response<ServiceWrapper> objResponse = response.Content.ReadAsAsync<Response<ServiceWrapper>>().Result;
if (objResponse != null)
{
if (objResponse.isSuccess == true)
{
listContact = objResponse.data.lContact;
int MaxPKinSelectedRecords = objResponse.data.MaxPKinSelectedRecords;
int MaxPKinTotalRecords = objResponse.data.MaxPKinTotalRecords;
if (listContact != null && listContact.Count>0)
{
try
{
Parallel.ForEach(listContact, contact =>
{
// some code...
});
// Recursive Call
if (MaxPKinTotalRecords != MaxPKinSelectedRecords)
{
ServiceFunctionality();
}
}
catch (Exception ex)
{
// Logging
}
}
}
else
{
// Logging
}
}
else
{
// Logging
}
}
catch (Exception ex)
{
// Logging
}
}
You can always unwind to a while loop. Because your calls aren't altering state, this is trival.
public void ServiceFunctionality()
{
bool done = false;
while(!done) {
try
{
done = true; //if we don't reset this, we're done.
// Get Data From WEBAPI
HttpClient client = new HttpClient();
HttpResponseMessage response = response = client.GetAsync("webapi url link").Result;
Response<ServiceWrapper> objResponse = response.Content.ReadAsAsync<Response<ServiceWrapper>>().Result;
if (objResponse != null)
{
if (objResponse.isSuccess == true)
{
listContact = objResponse.data.lContact;
int MaxPKinSelectedRecords = objResponse.data.MaxPKinSelectedRecords;
int MaxPKinTotalRecords = objResponse.data.MaxPKinTotalRecords;
if (listContact != null && listContact.Count>0)
{
try
{
Parallel.ForEach(listContact, contact =>
{
// some code...
});
// set loop variable
if (MaxPKinTotalRecords != MaxPKinSelectedRecords)
{
done = false;
}
}
catch (Exception ex)
{
// Logging
}
}
}
else
{
// Logging
}
}
else
{
// Logging
}
}
catch (Exception ex)
{
// Logging
}
}
}
Do not use recursion for calling a function whenever you have alternate suitable solution. I personally almost never do
I have tried to keep it same other than using a while..
Do not forget to break your loop. I tried to handle this thing but still
Just to be very careful, never take a risk of infinite loop on server I took maxPossibleIterations. So that in case of any mistake your web service server would not have to go for infinite iterations
public void ServiceFunctionality()
{
long maxPossibleIterations = 999999;
try
{
while (true)
{
maxPossibleIterations++;
// Get Data From WEBAPI
HttpClient client = new HttpClient();
HttpResponseMessage response = response = client.GetAsync("webapi url link").Result;
Response<ServiceWrapper> objResponse = response.Content.ReadAsAsync<Response<ServiceWrapper>>().Result;
if (objResponse != null)
{
if (objResponse.isSuccess == true)
{
listContact = objResponse.data.lContact;
int MaxPKinSelectedRecords = objResponse.data.MaxPKinSelectedRecords;
int MaxPKinTotalRecords = objResponse.data.MaxPKinTotalRecords;
if (listContact != null && listContact.Count>0)
{
try
{
Parallel.ForEach(listContact, contact =>
{
// some code...
});
if (MaxPKinTotalRecords == MaxPKinSelectedRecords)
{
break;
}
}
catch (Exception ex)
{
// Logging
}
}
else
break; //Important
}
else
{
// Logging
break;
}
}
else
{
// Logging
break;
}
} // End while
}
catch (Exception ex)
{
// Logging
}
}
I'm having a hard time tracing an exception within a Task. The message returned from the exception isn't helpful at all. Below is the method that appears to be throwing the exception:
public async Task<bool> TestProxy(IPEndPoint proxy)
{
Ping ping = new Ping();
PingReply reply = await ping.SendPingAsync(proxy.Address);
if (reply == null || reply.Status != IPStatus.Success) return false;
HttpClient client = new HttpClient();
HttpResponseMessage response;
try
{
response = await client.GetAsync("https://google.com");
} catch(Exception ex)
{
return false;
Console.WriteLine(ex.Message);
}
if(response.IsSuccessStatusCode)
{
return true;
}
else
{
return false;
}
And here is the calling code:
public async Task<List<IPEndPoint>> FetchWorkingProxiesAsync()
{
List<IPEndPoint> _proxies = await FetchRawProxiesAsync();
List<IPEndPoint> workingProxies = new List<IPEndPoint>();
Task[] tasks = new Task[_proxies.Count];
for(int i = 0; i < _proxies.Count; i++)
{
IPEndPoint _tmpProxy = _proxies[i];
tasks[i] = Task.Run(async () => {
try
{
if (await TestProxy(_tmpProxy))
{
workingProxies.Add(_tmpProxy);
}
}catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
}
await Task.WhenAll(tasks);
return workingProxies;
}
The exception that is being thrown is:
InnerException {"The request was aborted: The request was canceled."} System.Exception {System.Net.WebException}
When I set breakpoints no helpful information is available on the exception. I see that there's a System.Net.WebException but it doesn't say what or why.
I have CLR Throw and User Exceptions ticked in the Exceptions dialogue in VS.
Edit: I just realised I am not using the proxy to test the connection when attempting to connect to google.com. Even so, I'd still like to know how to find out more about the exception thrown.