Xamarin Forms - Error in iOS Attempting to JIT compile - xamarin.forms

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.

Related

How to correlate two AppInsights resources that communicate through NServiceBus?

Currently, I have dozens of .NET services hosted on various machines that show up as Resources on my AppInsights Application Map, which also shows their dependencies with respect to each other, based on the HTTP requests they make.
However, the relationships between services that communicate through NServiceBus (RabbitMQ) are not shown. Now, I am able to show the messages that are either sent or handled by a service via calls to TelemetryClient.TrackXXX(), but not connect Resources on the map using this information.
I have even gone so far as to attach the parent operation ID from the NSB message sender to the message itself, and assign it to the telemetry object in the receiver, but there is still no line drawn between the services in the Application Map.
To reiterate, this is what I'm getting in the Application Map:
(NSB Message Sender) --> (Message sent/handled)
And this is what I want:
(NSB Sender) --> (Receiver)
The services in question are .NET Core 3.1.
I cannot provide the code, as this is for my work, but any help would be greatly appreciated. I've searched everywhere, and even sources that seemed like they would help, didn't.
(not signed in, posting from work)
Alright, I finally got it. My approach to correlate AppInsights resources using their NSB communication is to mimic HTTP telemetry correlation.
Below is an extension method I wrote for AppInsights' TelemetryClient. I made a subclass named RbmqMessage:NServiceBus.IMessage, given my applications use RBMQ, and gave it the following properties for the sake of correlation (all set in the service that sends the message) :
parentId: equal to DependencyTelemetry.Id
opId: value is the same in the sender's DependencyTelemetry and the receiver's RequestTelemetry. Equal to telemetry.context.operation.id
startTime: DateTime.Now was good enough for my purposes
The code in the service that sends the NSB message:
public static RbmqMessage TrackRbmq(this TelemetryClient client, RbmqMessage message)
{
var msg = message;
// I ran into some issues with Reflection
var classNameIdx = message.ToString().LastIndexOf('.') + 1;
var messageClassName = message.ToString().Substring(classNameIdx);
var telemetry = new DependencyTelemetry
{
Type = "RabbitMQ",
Data = "SEND "+messageClassName,
Name = "SEND "+messageClassName,
Timestamp = DateTime.Now,
Target = "RECEIVE "+messageClassName //matches name in the service receiving this message
};
client.TrackDependency(telemetry);
msg.parentId = telemetry.Id;
msg.opId = telemetry.Context.Operation.Id; //this wont have a value until TrackDependency is called
msg.startTime = telemetry.Timestamp;
return msg;
}
The code where you send the NSB message:
var msg = new MyMessage(); //make your existing messages inherit RbmqMessage
var correlatedMessage = _telemetryClient.TrackRbmq(msg);
MessageSession.Publish(correlatedMessage); //or however the NSB message goes out in your application
The extension method in the NServiceBus message-receiving service:
public static void TrackRbmq(this TelemetryClient client, RbmqMessage message)
{
var classnameIdx = message.ToString().LastIndexOf('.')+1;
var telemetry = new RequestTelemetry
{
Timestamp = DateTime.Now,
Name = "RECEIVE "+message.ToString().Substring(classNameIdx)
};
telemetry.Context.Operation.ParentId = message.parentId;
telemetry.Context.Operation.Id = message.opId;
telemetry.Duration = message.startTime - telemetry.Timestamp;
client.TrackRequest(telemetry);
}
And finally, just track and send the message:
var msg = new MyMessage();
_telemetryClient.TrackRbmq(msg);
MessagePipeline.Send(msg); //or however its sent in your app
I hope this saves someone the trouble I went through.

Xamarin Offline Sync issue with getting data

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

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.

Microsoft Speech Recognition in webservices is not returning the result

Well i'm using Microsoft Speech Platform SDK 10.2.
I made a asp.Net WebService application and most of the WebServices works fine (HelloWorld(), etc...), but I have one service that uses the SpeechRecognitionEngine and when I deploy the application and try to run this webservice I get no result, i.e, I can see through the debug mode that it reaches the return line, but when I call it trought the browser the page keeps loading for ever, without any response.
Here's a sample of the code:
[WebMethod]
public bool voiceRecognition() {
SpeechRecognitionEngine sre = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("pt-PT"));
Choices c = new Choices();
c.Add("test");
GrammarBuilder gb = new GrammarBuilder();
gb.Append(c);
Grammar g = new Grammar(gb);
sre.LoadGrammar(g);
sre.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
//// just for Testing
RecognitionResult result = null;
if (result != null) {
return true;
} else {
return false;
}
}
Note: I'm using IIS to deploy the WebService Application.
If someone have some thoughts please let me know.
I don't know if you've found your answer or not. When trying to solve this myself a couple of days ago, I stumbled across your question and it matched our circumstances to a "T".
In order to fix it all we had to do was put...
sre.RecognizeAsyncStop();
sre.Dispose();
where "sre" is your SpeechRecognitionEngine variable. If you don't stop it and dispose of it at the end of your web service then the web service won't return.
Hope this helps. :)

Resources