Forum Xamarin.Forms

Can I pass a custom function pointer, or callback through another thread stack?

JKnottJKnott Member ✭✭✭

I have a camera function that is giving me a hard time.
When the user selects the option to add a photo to the record in the app, the code launches a popup, to ask options for the image, but the thread continues on since the PopupView is non Awaitable.
There are only two ways I can think to handle this,

  1. Create an awaitable popup view, this would then block the main thread until the photo has been taken, and can refresh the display after the picture is processed and added to the DB.
  2. Create a callback that when the image has been taken, and is added to the db, it can call, that will refresh the display either by adding the taken image to the CarouselView or just signal to refresh display by rerunning the Repository<T>().GetItems() call. The main problem with this I can see, is that since the callback would be called from a different thread, I wouldn't necessarily have access to the instance of the database object on the display. (I could try some ExecuteOnMainThread type thing, but I don't know how well that would work.
  3. In the old days, I would have created a DoWhile thread that refreshes the database objects on the screen, blocked on a GlobalClass.Semaphore and then signal that same Global.Semaphore from the camera function.

I don't know, perhaps that is the best method to use for this? I always figured C# is just a easier to use more automated C++. I just don't know enough about standards of C# threading vs C/C++. In some ways I miss the old Main thread loop, other times, I am glad to not have to deal with it....

Any advice greatly appreciated!

Cheers!

Answers

  • JKnottJKnott Member ✭✭✭
    edited February 22

    Extension of this question.

    I am using an AsyncronousInitializer interface I created for my ViewModels. All of my ViewModel classes are inherited from a BaseViewModel class. I have decided to move the IAsyncInitializer interface to the BaseViewModel. By doing this, I can basically create a simple function in the base class.

    internal void RefreshDatabase()
    {
        GlobalClass.dbSemaphore.Wait();
        Initialization();
    }
    

    In the function I need to use this, I can then call it like this

    private void GetPhotoFromCamera()
    {
        .....
    
        MyPhotoClass p = new MyPhotoClass 
        {
            ParentRecord = viewModel.Id,
            Category = viewModel.Category,
        }
        viewModel.RefreshDatabase();
    
        GetPhoto.TakePicture(p);
    
        ....
    }
    

    Then in my GetPhoto class

    public static void TakePicture(MyPhotoClass p)
    {
        ...
        <take photo code>
        ... 
    
        GlobalClass.dbSemaphore.Release();
    }
    

    The problem is, How should I create the interface in the BaseViewModel?

        Task IAsyncInitialization.Initialization { get; }
    

    or

    Task Initialization { get; }
    

    Implicit, vs Local.

    I need to overload the Initialization() function in each of the child classes, so I am not sure which method would work better?

  • JKnottJKnott Member ✭✭✭

    Sorry, I think I've figured out part of my problem with the BaseViewModel idea.
    I cannot overload the base implementations of the interface. I will have to implement the interface and the function in each of the ViewModels that need it.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    You can use MediaPlugin and MVVM to achieve it, this plugin could have async/await method, If you do not need it, please share a demo or related code that could reproduce this issue.

  • JKnottJKnott Member ✭✭✭

    @LeonLu Hello, I'm sorry this is more or less a duplicate thread to the other one we are talking on. Same issue, I accidentally created the other thread as a mistake.
    The issue is the same in both. The other thread has more code and in depth descriptions, so I would continue the discussion there if you like.

    Thanks again!

Sign In or Register to comment.