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.
Related
I am trying to do a GATT write operation in a BLE after Notification where I am getting the value from server. The write operation works fine when there is no prior GATT operation like Notification. So this is the code where I am reading the value through notification
public async Task ReadConfigData(ICharacteristic characteristics)
{
if (characteristics != null)
{
try
{
await _adapter.ConnectToDeviceAsync(_device);
characteristics.ValueUpdated += (o, e) =>
{
Device.BeginInvokeOnMainThread(async () =>
{
//var readvalue2 = characteristics.Value;
var bytes = e.Characteristic.Value;
//var readvalue = await characteristics.ReadAsync();
BLEresultnew = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine(BLEresultnew);
//if(BLEresultnew.Contains("start"))
//{
concat += BLEresultnew;
//}
});
};
await characteristics.StartUpdatesAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
This is how I am doing the write operation
public async task WriteDataAsync(String data)
{
if (_characteristicsBLE != null)
{
try
{
// await _adapter.ConnectToDeviceAsync(_device);
byte[] senddata = Encoding.UTF8.GetBytes(data);
int start = 0;
while (start < senddata.Length)
{
int chunkLength = Math.Min(20, senddata.Length - start);
byte[] chunk = new byte[chunkLength];
Array.Copy(senddata, start, chunk, 0, chunkLength);
Device.BeginInvokeOnMainThread(async () =>
{
await Task.Delay(300);
await _characteristicsBLE.WriteAsync(chunk);
});
start += 20;
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
I have even called the write operation in main thread to avoid any threading issue. But still I get GATT error. I have no clue how to fix this any suggestions?
Hi guy's i'm trying to figure out a way to display a DisplayAlert Popup when Someone entered the Wrong details into the Login Process.
Issue is, The login's a little "Weird" I'm not comparing against a Database i'm comparing against a List of Customers I get from a APi So I have to loop threw to then find if the detail's are correct.
I have a login Phase 1() which Checks against the Wordpress API but I want to have this be able to notify on Phase 1 and 2, Phase 1 is a Username = Username Password = Password Where phase 2 is just a Username = Username , I know it's not secure The Login is more of a Formality then anything.
public async void Login_Phase1()
{
try
{
#region Login Phase 1
var client = new WordPressClient("http://XXX.co.za/wp-json/");
client.AuthMethod = AuthMethod.JWT;
try
{
await client.RequestJWToken(Usernamelabel.Text, Password.Text);
}
catch (Exception e)
{
await App.Current.MainPage.DisplayAlert("Something Went wrong", e.ToString(), "OK");
}
var x = client;
var isValidToken = await client.IsValidJWToken();
WpApiCredentials.token = client.GetToken();
if (isValidToken)
{
Login_Phase2();
}
else
{
await App.Current.MainPage.DisplayAlert("Detail's are Incorect", "Token not Found", "OK");
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
#endregion
}
public void Login_Phase2()
{
try
{
#region login Phase 2
var list = FetchCustomers.customers.ToList();
foreach (var user in list)
{
if (user.username == Usernamelabel.Text)
{
Preferences.Set("CId", user.id.ToString());
Preferences.Set("Token", WpApiCredentials.token);
Preferences.Set("CUsername", user.username);
Preferences.Set("CEmail", user.email);
Users.Loggedin = true;
Application.Current.SavePropertiesAsync();
App.Current.MainPage.DisplayAlert("Complete", "Login Process Complete, Enjoy", "OK");
App.Current.MainPage = new Home("Mica Market");
}
//Want to add a Display popup Here to say the information is entered incorrectly, but
not have it repeat 200 Time's
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
#endregion
}
Fetching all the Customers to check against
private async void ExtractWooData(List<Customer> x)
{
try
{
#region FetchC
RestAPI rest = new RestAPI("http://xxxxxx/wp-json/wc/v3/", "ck_a25xxxxxxxxxxx0", "cs_8xxxxxxxx8xxxx");
WCObject wc = new WCObject(rest);
int pageNum = 1;
var isNull = false;
List<Customer> oldlist;
while (!isNull)
{
var page = pageNum.ToString();
x = await wc.Customer.GetAll(new Dictionary<string, string>() {
{
"page", page
}, {
"per_page", "100"
}
});
oldlist = FetchCustomers.customers ?? new List<Customer>();
if (x.Count == 0)
{
break;
}
else
{
//1st loop customers needs to = 100
//2nd loop oldist needs to = 40+
//If count = 0 then => Combine Customers + Oldist
pageNum++;
FetchCustomers.customers = oldlist.Union(x).ToList();
}
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
#endregion
}
Any Advice?
you can replace the foreach with a LINQ query
// find the first match
var found = list.Where(user => user.username == Usernamelabel.Text).FirstOrDefault();
if (found != null)
{
// set preferences and navigation
}
else
{
// DisplayAlert
}
I'm writing a program that makes remote desktop connection with signalr. I keep sending screenshots (in the .net client) for it. But when I reconnect to the server after a while, I get error: Connection started reconnecting before invocation result was received.
public void ImageMain()
{
var querstring = new Dictionary<string, string>();
querstring.Add("userid", "sessionlocal");
var hubConnectionMouse = new HubConnection("http://localhost:8089/", querstring);
Program p = new Program();
IHubProxy myHubProxyMouse = hubConnectionMouse.CreateHubProxy("MyHub");
string a = "";
try
{
hubConnectionMouse.Start().Wait();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
byte[] ekran;
while (true)
{
ekran = null;
ekran = EkranGoruntusu();
if (ekran.Length < 80000)
{
try
{
myHubProxy.Invoke("addMessage", "sessionlocal", ekran).ContinueWith(task =>
{
if (task.IsFaulted)
{
Console.WriteLine("!!! image gönderilirken hata olıştu:{0} \n",
task.Exception.GetBaseException() + "tekrar bağlanılıyor....");
}
else
{
Console.WriteLine("Add messgae" + " gonderilecek ekran boyutu " + ekran.Length);
Console.WriteLine("hub durumu" + hubConnection.State);
}
}).Wait();
}
catch (Exception exception)
{
Console.WriteLine("bağlantı hatas tekrar bağlanılıyor" + exception.Message);
Console.ReadKey();
}
}
else
{
Console.WriteLine("gonderilcek goruntü cok büyük");
}
}
Console.ReadLine();
}
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 using C# and Windows Phone 8.1 as Universal.
I Have an issue with BackgroundDownloader. when I start a downloader, it gave me an exception:
Downloading http://localhost/MySong.mp3 to MySong.mp3 with Default priority, a95c00db-738d-4e22-a456-dc30d49b0a3b
A first chance exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Exception: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
here is my code:
private void downladButton_Tapped(object sender, TappedRoutedEventArgs e)
{
PumpUrl(txtUrl.Text);
}
async void PumpUrl(string url)
{
if (!string.IsNullOrEmpty(url) && CheckUrl(url))
StartDownloadMethod(url);
else
await new MessageDialog("Looks like URL is invalid.\r\nPlease check your URL and try again"").ShowAsync();
}
public bool CheckUrl(string URL)
{
Uri source;
if (Uri.TryCreate(URL, UriKind.RelativeOrAbsolute, out source))
return true;
else
return false;
}
public void StartDownloadMethod(string url, string fileName = null)
{
StartDownload(url, BackgroundTransferPriority.Default, false, fileName);
}
private async void StartDownload(string url, BackgroundTransferPriority priority, bool requestUnconstrainedDownload, string fileName = null)
{
Uri source;
if (!Uri.TryCreate(url.Trim(), UriKind.RelativeOrAbsolute, out source))
{
Debug.WriteLine("Invalid URI.");
return;
}
string destination = null;
if (string.IsNullOrEmpty(fileName))
try
{
destination = System.IO.Path.GetFileName(Uri.UnescapeDataString(url)).Trim();
}
catch { }
else
destination = Uri.UnescapeDataString(fileName).Trim();
if (string.IsNullOrWhiteSpace(destination))
{
Debug.WriteLine("A local file name is required.");
return;
}
StorageFile destinationFile = null;
try
{
if (vars.localType == LocalType.SDCard)
destinationFile = await KnownFolders.RemovableDevices.CreateFileAsync(
"Downloads\\Test App\\" + destination, CreationCollisionOption.GenerateUniqueName);
else
destinationFile = await KnownFolders.MusicLibrary.CreateFileAsync(
"Test App\\" + destination, CreationCollisionOption.GenerateUniqueName);
}
catch (FileNotFoundException ex)
{
Debug.WriteLine("Error while creating file: " + ex.Message);
return;
}
catch (Exception ex) { Debug.WriteLine("Error while creating file: " + ex.Message); }
if (destinationFile == null)
return;
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(source, destinationFile);
Debug.WriteLine(String.Format(CultureInfo.CurrentCulture, "Downloading {0} to {1} with {2} priority, {3}",
source.AbsoluteUri, destinationFile.Name, priority, download.Guid));
download.Priority = priority;
Add(url, destination, download);
if (!requestUnconstrainedDownload)
{
// Attach progress and completion handlers.
await HandleDownloadAsync(download, true);
return;
}
List<DownloadOperation> requestOperations = new List<DownloadOperation>();
requestOperations.Add(download);
UnconstrainedTransferRequestResult result;
try
{
result = await BackgroundDownloader.RequestUnconstrainedDownloadsAsync(requestOperations);
}
catch (NotImplementedException)
{
Debug.WriteLine(
"BackgroundDownloader.RequestUnconstrainedDownloadsAsync is not supported in Windows Phone.");
return;
}
Debug.WriteLine(String.Format(CultureInfo.CurrentCulture, "Request for unconstrained downloads has been {0}",
(result.IsUnconstrained ? "granted" : "denied")));
await HandleDownloadAsync(download, true);
}
private async Task HandleDownloadAsync(DownloadOperation download, bool start)
{
try
{
Debug.WriteLine("Running: " + download.Guid);
bool bb = false;
foreach (DownloadOperation item in DownloadDB.activeDownloads)
{
if (item != null && item.Guid == download.Guid)
{
bb = true;
break;
}
}
if (!bb)
DownloadDB.activeDownloads.Add(download);
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
CancellationTokenSource cts = new CancellationTokenSource();
AppendCancellationTokenSource(download, cts);
if (start)
await download.StartAsync().AsTask(cts.Token, progressCallback);
else
await download.AttachAsync().AsTask(cts.Token, progressCallback);
ResponseInformation response = download.GetResponseInformation();
DownloadDB.RemoveChildByGuid(download.Guid.ToString());
DownloadDB.SaveDB();
Debug.WriteLine(String.Format(CultureInfo.CurrentCulture, "Completed: {0}, Status Code: {1}",
download.Guid, response.StatusCode));
}
catch (TaskCanceledException taskCanceled)
{
Debug.WriteLine("TaskCanceledException: " + download.Guid + "\t" + taskCanceled.Message);
DownloadDB.RemoveChildByGuid(download.Guid.ToString());
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
}
finally
{
DownloadDB.RemoveChildByGuid(download.Guid.ToString());
DownloadDB.activeDownloads.Remove(download);
}
}
I used my code in other application 3 month ago and it works fine but in this application dosent work. Where I wrong?
Thanks