Xamarin Offline Sync issue with getting data - sqlite

I am getting some issues returning data from azure mobile backend api using android emulator. The mobile app is written with Xamarin and I am using MobileServiceClient and IMobileServiceSyncTable. The following is what I have coded:
var _mobileServiceClient = new MobileServiceClient(url);
var store = new MobileServiceSQLiteStore("notesdb.db");
store.DefineTable<Notes>();
_mobileServiceClient.SyncContext.InitializeAsync(store);
var _notesTable = _mobileServiceClient.GetSyncTable<Notes>();
var temp = await _notesTable.ReadAsync();
Backend code is as followed:
public IQueryable<Notes> GetAllNotes()
{
return Query();
}
Whenever I do that, the app will become unresponsive and never returned. Its like it is in deadlock mode.
Has anyone had this problem?

After looking at the MobileServiceClient usage: https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-dotnet-how-to-use-client-library
Your calls seem fine except one:
_mobileServiceClient.SyncContext.InitializeAsync(store);
Since you are not awaiting this method, the sync context will not be initialized for your next methods.
So just await the method and you should be fine:
await _mobileServiceClient.SyncContext.InitializeAsync(store);
One general rule your can apply almost everytime: always await the methods returning Task objects.
Also since you are in the service/repository layer, you should ConfigureAwait(false) your methods:
var _mobileServiceClient = new MobileServiceClient(url);
var store = new MobileServiceSQLiteStore("notesdb.db");
store.DefineTable<Notes>();
await _mobileServiceClient.SyncContext.InitializeAsync(store).ConfigureAwait(false);
var _notesTable = _mobileServiceClient.GetSyncTable<Notes>();
var temp = await _notesTable.ReadAsync().ConfigureAwait(false);
Doing that your code won't run in the UI thread (well it's not guaranteed but I don't want to confuse you :). Since you are not running the code on the same thread, it will also reduce possible deadlocks.
more on that: https://medium.com/bynder-tech/c-why-you-should-use-configureawait-false-in-your-library-code-d7837dce3d7f

Related

Xamarin Forms - Error in iOS Attempting to JIT compile

I have a xamarin forms app. When I compile and test on my Pixel3, everything seems to be working properly. When I load it up in my iOS device running iOS13.something, I get the following error when I try to make my second call to a web service in my app. The error is shown below.
Assertion at /Users/builder/jenkins/workspace/archive-mono/2019-08/ios/release/mono/mini/interp/interp.c:2160, condition `is_ok (error)' not met, function:do_jit_call, Attempting to JIT compile method '(wrapper other) void object:gsharedvt_out_sig (object&,single&,int&,intptr)' while running in aot-only mode. See https://learn.microsoft.com/xamarin/ios/internals/limitations for more information. assembly: type: member:(null)
The code is a bit of a mess, but has been working in the past.
var uri = String.Format("{0}//{1}/{2}?PlayerToken={3}", protocol, servername, tournamentsInClubUrl, userToken);
var httpC = new HttpClient();
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
requestMessage.Headers.Add("AppKey", AppKey);
var body = await httpC.SendAsync(requestMessage); <-- Error happens here.
var str = await body.Content.ReadAsStringAsync();
var res = JsonConvert.DeserializeObject<List<PicVideoApp.Models.TournamentInfo>>(str);
httpC.Dispose();
httpC = null;
return res;
I assume that I am doing something wrong, but danged if I can see it. Any ideas are appreciated.
It runs properly in the iOS Simulator.
TIA.
From shared error info , you need to use C# delegate to call native functions .
To call a native function through a C# delegate, the delegate's declaration must be decorated with one of the following attributes:
UnmanagedFunctionPointerAttribute (preferred, since it is cross-platform and compatible with .NET Standard 1.1+)
MonoNativeFunctionWrapperAttribute
For example :
[MonoNativeFunctionWrapper]
delegate void SomeDelegate (int a, int b);
//
// the ptrToFunc points to an unmanaged C function with the signature (int a, int b)
void Callback (IntPtr ptrToFunc)
{
var del = (SomeDelegate) Marshal.GetDelegateForFunctionPointer (ptrToFunc, typeof (SomeDelegate));
// invoke it
del (1, 2);
A similar error was thrown at me in iOS when I used dynamic types in my code. I was able to solve it by enabling the 'Mono Interpreter' in iOS build settings. Hope that helps in your case.

How do I do an EF Database.ExecuteSQLCommand async?

Here's the code that I am using:
public async Task<IHttpActionResult> NewTopicTests([FromBody] NewTopicTestsDTO testSpec)
{
var sql = #"dbo.sp_new_topic_tests #Chunk";
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("#Chunk", testSpec.Chunk)
};
int result = db.Database.ExecuteSqlCommand(sql, parameters);
await db.SaveChangesAsync();
return Ok();
}
Can someone confirm if this is the correct way to do this using async? In particular do I need to do this:
int result = db.Database.ExecuteSqlCommand(sql, parameters);
await db.SaveChangesAsync();
Note that the code works however I am having a problem with my application where it suddenly stops without any error message. I am looking into every possible problem.
What's being saved here ? I think there is no need to call save changes here.
Remove save changes and you will see the same behavior, because any changes you've made in your stored procedure, are not tracked by entity framework context.
And you can rewrite your code as following:
int result = await db.Database.ExecuteSqlCommandAsync(sql, parameters);
Have you checked every where to find the reason of your problem ? Windows Error Log etc ?
Go to Debug menu of Visual Studio IDE, and open Exceptions, then check both 'throw' and 'user_unhandled' for 'Common Language Runtime Exceptions' and test your code again.

asp.net app calling service says its not initialized?

So this code runs in an asp.net app on Linux. The code calls one of my services. (WCF doesn't work on mono currently, that is why I'm using asmx). This code works AS INTENDED when running from Windows (while debugging). As soon as I deploy to Linux, it stops working. I'm definitely baffled. I've tested the service thoroughly and the service is fine.
Here is the code producing an error: (NewVisitor is a void function taking 3 strings in)
//This does not work.
try
{
var client = new Service1SoapClient();
var results = client.NewVisitor(Request.UserHostAddress, Request.UrlReferrer == null ? String.Empty : Request.UrlReferrer.ToString(), Request.UserAgent);
Logger.Debug("Result of client: " + results);
}
Here is the error generated: Object reference not set to an instance of an object
Here is the code that works perfectly:
//This works (from the service)
[WebMethod(CacheDuration = _cacheTime, Description = "Returns a List of Dates", MessageName = "GetDates")]
public List<MySqlDateTime> GetDates()
{
return db.GetDates();
}
//Here is the code for the method above
var client = new Service1Soap12Client();
var dbDates = client.GetDates();
I'd love to figure out why it is saying that the object is not set.
Methods tried:
new soap client.
new soap client with binding and endpoint address specified
Used channel factory to create and open the channel.
If more info is needed I can give more. I'm out of ideas.
It looks like a bug in mono. You should file a bug with a reproducible test case so it can be fixed (and possibly find a workaround you can use).
Unfortunately, I don't have Linux to test it but I'd suggest you put the client variable in an using() statement:
using(var client = new Service1SoapClient())
{
var results = client.NewVisitor(Request.UserHostAddress, Request.UrlReferrer == null ?
String.Empty : Request.UrlReferrer.ToString(), Request.UserAgent);
Logger.Debug("Result of client: " + results);
}
I hope it helps.
RC.

Multiple instances of views in PureMVC: Am I doing this right?

What I'm doing NOW:
Often multiple instances of the view component would be used in multiple places in an application. Each time I do this, I register the same mediator with a different name.
When a notification is dispatched, I attach the name of the mediator to the body of the notification, like so:
var obj:Object = new Object();
obj.mediatorName = this.getMediatorName();
obj.someParameter = someParameter;
sendNotification ("someNotification", obj);
Then in the Command class, I parse the notification body and store the mediatorName in the proxy.
var mediatorName:String = notification.getBody().mediatorName;
var params:String = notification.getBody().someParameter;
getProxy().someMethod(params, mediatorName);
On the return notification, the mediatorName is returned with it.
var obj:Object = new Object();
obj.mediatorName = mediatorName;
obj.someReturnedValue= someReturnedValue;
sendNotification ("someReturnedNotification", obj);
In the multiple mediators that might be watching for "someReturnedNotification," in the handleNotification(), it does an if statement, to see
if obj.mediatorName == this.getMediatorName
returns true. If so, process the info, if not, don't.
My Question is:
Is this the right way of using Multiton PureMVC? My gut feeling is not. I am sure there's a better way of architecting the application so that I don't have to test for the mediator's name to see if the component should be updated with the returned info.
Would someone please help and give me some direction as to what is a better way?
Thanks.
I checked with Cliff (the puremvc.org guy) and he said it's fine.

Oracle query fired off, then never returns

I have this problem in my ASP.NET application where I'm seeing some of my Oracle queries fired off to the server then not returning. Ever. It happens in several places in my app and I can't explain it. Here's one specific scenario where I'm seeing this behavior:
During application start-up I am pre-fetching data asynchronously into the application state (the choice was made to use app state instead of cache b/c the data never changes during the lifetime of the app).
Action<string, object> AddApplicationState = (string name, object data) =>
{
Application.Lock();
Application.Add(name, data);
Application.UnLock();
};
Func<DataTable> GetFullNames = () => Database.GetAllNames();
Func<DataTable> GetProvinceNames = () => Database.GetProvinceNames();
Func<DataTable> GetTribeNames = () => Database.GetTribeNames();
GetFullNames.BeginInvoke(result => AddApplicationState("AllNames", GetFullNames.EndInvoke(result)), null);
GetProvinceNames.BeginInvoke(result => AddApplicationState("ProvinceNames", GetProvinceNames.EndInvoke(result)), null);
GetTribeNames.BeginInvoke(result => AddApplicationState("TribeNames", GetTribeNames.EndInvoke(result)), null);
The second two return just fine, but the first either never returns or returns after about 10 minutes. After firing up Oracle SQL Developer I go to the 'monitor sessions' tool and can see a single session for the query. It looks like it has completed, b/c the wait time is (null) and the session is inactive. Here's the ADO.NET code used to query the database:
public static DataTable GetAllNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT NAME_ID, NATIVE_NAME, NVL(FREQUENCY,0) \"FREQUENCY\", CULTURE_ID,");
sql.AppendLine("ENGLISH_NAME, REGEXP_REPLACE(ENGLISH_NAME, '[^A-Za-z]', null) \"ENGLISH_NAME_STRIPPED\"");
sql.AppendLine("FROM NAMES");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dtAllNames = new DataTable();
orada.Fill(dtAllNames);
return dtAllNames;
}
}
}
public static DataTable GetTribeNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
var sql = new StringBuilder();
sql.AppendLine("SELECT DISTINCT NAME_ID, English_Name \"TRIBE_NAME_ENGLISH\",");
sql.AppendLine("REGEXP_REPLACE(English_Name, '[^A-Za-z]',null) \"TRIBE_ENGLISH_NAME_STRIPPED\",");
sql.AppendLine("NATIVE_NAME \"TRIBE_NATIVE_NAME\"");
sql.AppendLine("FROM NAMES");
sql.AppendLine("WHERE NAME_ID IN ");
sql.AppendLine("(SELECT NAME_ID_TRIBE FROM TRIBES UNION SELECT NAME_ID_FAMILY FROM TRIBES)");
sql.AppendLine("ORDER BY English_Name");
oracmd.CommandText = sql.ToString();
var orada = new OracleDataAdapter(oracmd);
var dt = new DataTable();
orada.Fill(dt);
return dt;
}
}
}
public static DataTable GetProvinceNames()
{
using (OracleConnection oraconn = GetConnection())
{
using (OracleCommand oracmd = GetCommand(oraconn))
{
oracmd.CommandText = "SELECT DISTINCT PROVINCE_ID, PROVINCE_NAME_NATIVE, PROVINCE_NAME_ENGLISH FROM PROVINCES";
var orada = new OracleDataAdapter(oracmd);
var dtRC = new DataTable();
orada.Fill(dtRC);
return dtRC;
}
}
}
As you can see, the ADO.NET code is pretty standard (and boring!) stuff. When run in SQL Developer, the queries return less than a second. The first query returns x rows, the second x rows, and the third x rows. But this problem of queries being fired off then never returning happens often and I can't seem to track down the issue. Anyone have any thoughts?
And finally, since I realize it could be something completely unrelated to code, I am running the app locally (from Visual Studio) on a Windows XP SP3 machine and connecting via VPN to a remote Oracle 10g Enterprise instance running on Windows 2003 Server. Locally, I have installed Oracle Data Access Components v11.1.0.6.20.
Thanks!
Are you watching your output window for any exceptions? I don't see any catch blocks in your code.
Oracle's ODP.net has almost exactly the same syntax as ADO, but performs better in many situations. If you're only using Oracle, it might be worth a look.
Is there a reason to use StringBuilder? A single string variable will perform better and makes code easier to read.
It seems that the queries were actually returning, just taking a very long time due to poor query performance, low bandwidth, and the enormous amount of rows being returned. The VS debugger seems to give up after a few seconds for these long-running queries. However, if I let it sit for a few minutes my breakpoints would get hit and things would work as expected.
Thanks for the replies / comments!

Resources