A Microsoft framework for building cross-platform mobile apps using .NET and C# with native performance and user interfaces.
Reenterant code in xamarin.Forms project nulling out local varibles.
Okay, I've asked this before, and gotten a few work arounds that seem to work, but I would like to know what is happening here, and if there is any way I can prevent this from happening?
When I load a page in the Navigation stack, it is calling the constructor twice? My constructor calls a function to initialize data types used in the page, but it's being called twice, once it has the appropriate info, but the second time it executes the incoming variable that's passed to the constructor is null
Here is the latest instance that I am having the problem with
This is the code that creates the page that is being loaded.
private async void btAddShot_Clicked(object sender, EventArgs e)
{
btUpdateRecord_Clicked(null, null);
try
{
if (Navigation.NavigationStack[Navigation.NavigationStack.Count - 1].GetType() != typeof(ShotRecordEntry))
{
await Navigation.PushAsync(new ShotRecordEntry(new ShotDataViewModel(viewModel.MyElement)));
}
}
catch (Exception ex)
{
GeneralExceptionHandler.Log(ex);
}
}
Please note that I was having the problem here as well, and the page was loading twice into the stack.
The code above prevents the page from doubling onto the stack.
Here is my constructor for the page to be loaded
public LogBookWeapon MyWeapon ;
/// <summary>
/// Default simple constructor.
/// </summary>
public ShotDataViewModel(LogBookWeapon d)
{
MyWeapon = d;
InitializeViewModel();
}
then the function to initialize the other variables and data members in the class.
/// <summary>
/// Format and build the base data.
/// </summary>
private async void InitializeViewModel()
{
if (MyWeapon.Id > 0)
{
Title = "Shot Information";
LogRecord = await new LogBookRepository().GetRecordByID(MyWeapon.LogEntryPk);
MyShot = new Shot();
MyShot.LogWpnId = MyWeapon.Id;
ShotRecord = await new ShotRepository().GetItemByParentID(MyWeapon.Weaponpk);
}
else
{
LogRecord = new LogEntry();
MyShot = new Shot();
ShotRecord = new ObservableCollection<Shot>();
}
}
This code is executing twice, the first pass, it works as expected, the local variable MyWeapon is populated with the data that was passed in the constructor.
But the second time the code executes the local variable is now null.
The work around that I have used in the past is to set a SemaphoreSlim
/// <summary>
/// Defines the Semaphore
/// </summary>
private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
and then in my critical code path I would execute.
try
{
await Semaphore.WaitAsync(0).ConfigureAwait(true);
........ critical code......
}
catch (Exception ex)
{
GeneralExceptionHandler.Log(ex);
}
finally
{
Semaphore.Release();
}
This work around should work in my new instance where I am having a problem. I have not implemented this fix yet, but would like to understand why this issue is occurring, so I can fix any sort of problem that is causing it.
Any help greatly appreciated!
Cheers!
Developer technologies | .NET | Xamarin
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.