How I can fix the warning about locationManagerDidChangeAuthorization and authorizationStatus in #Xamarin.Forms?

huangapple go评论81阅读模式
英文:

How I can fix the warning about locationManagerDidChangeAuthorization and authorizationStatus in #Xamarin.Forms?

问题

首先,我做了一些研究,但只找到了适用于Swift的iOS本机答案。

完整的警告消息如下:

此方法如果在主线程上调用可能会导致UI无响应。相反,考虑等待-locationManagerDidChangeAuthorization:回调并首先检查authorizationStatus

我已经阅读了这可能是因为我在使用异步调用。我也阅读了有关iOS版本的信息:StackOverFlow/73805219
我应该如何在Xamarin Forms中修复这个问题?

我必须说我正在使用#Xamarin.Forms.Essentials中的Geolocalization来在异步函数中获取当前的经度和纬度,然后通过#MessaginCenter发送它。

async Task StoringNoteAsync()
{
    Location location = await _geolocation.GetCurrentLocation();


    NoteSelected = NoteSelected ?? new Note();


    NoteSelected.Title      = Title;
    NoteSelected.Content    = Content;
    NoteSelected.CreatedAt  = DateTime.Now;
    NoteSelected.iNoteType  = (int)SelectedNoteType;
    NoteSelected.Longitude  = location.Longitude;
    NoteSelected.Latitude   = location.Latitude;


    //_noteService.SaveNote( NoteSelected );


    MessagingCenter.Instance.Send( this, "upsert", NoteSelected );


    await _navigation.PopAsync();
}
英文:

First of all, I did a little research but only found for Swift a native iOS answer.

The complete warning says:

This method can cause UI unresponsiveness if invoked on the main thread. Instead, consider waiting for the `-locationManagerDidChangeAuthorization:` callback and checking `authorizationStatus` first.

I have read that could be because I am using an async, away call; as well. I have read about the iOS version also: StackOverFlow/73805219
How I can fix this in Xamarin forms?

I must say that I am using Geolocalization from #Xamarin.Forms.Essentials to get the current longitud and latitude in an async function that I send by #MessaginCenter.

async Task StoringNoteAsync()
        {
            Location location = await _geolocation.GetCurrentLocation();


            NoteSelected = NoteSelected ?? new Note();


            NoteSelected.Title      = Title;
            NoteSelected.Content    = Content;
            NoteSelected.CreatedAt  = DateTime.Now;
            NoteSelected.iNoteType  = (int)SelectedNoteType;
            NoteSelected.Longitude  = location.Longitude;
            NoteSelected.Latitude   = location.Latitude;


            //_noteService.SaveNote( NoteSelected );


            MessagingCenter.Instance.Send( this, "upsert", NoteSelected );


            await _navigation.PopAsync();
        }

答案1

得分: 0

以下是翻译好的内容:

听起来你正在UI线程上运行代码,需要在不同的线程上运行代码。

使用 Task.Run 切换到后台线程。

由于你在一个 async 方法中,并且已经在主线程上运行,可以这样做:

async Task MyMethod()
{
    // "await",以便在此代码完成之前不运行下面的 "additional code"。
    // "async" 只在块中的代码使用 "await" 时需要。
    await Task.Run( async () =>
    {
        // 需要在后台线程上运行的代码...
    });

    // 需要在原始线程上运行的附加代码...
    ...
}

在主线程上显式运行附加代码的替代方法

async Task MyMethod()
{
    // (这部分与第一个代码片段相同。)
    // "await",以便在此代码完成之前不运行下面的 "additional code"。
    // "async" 只在块中的代码使用 "await" 时需要。
    await Task.Run( async () =>
    {
        // 需要在后台线程上运行的代码...
        // 例如,不涉及UI的长时间运行逻辑。
    });

    // (这部分显式在主线程上运行。)
    // "async" 只在块中的代码使用 "await" 时需要。
    await MainThread.InvokeOnMainThreadAsync( async () =>
    {
        // 需要在主线程上运行的代码(影响UI)...
    });
}
英文:

Sounds like you are on the UI thread, and need to run code on a different thread.

Use Task.Run to get to a background thread.

Since you are in an async method, and you are already running on MainThread, do it like this:

async Task MyMethod()
{
    // "await", so that "additional code" below is not run until this code finishes.
    // "async" is only needed if code in block uses "await".
    await Task.Run( async () =>
    {
        // code that needs to run on a background thread...
    });

    // additional code, that needs to run on the original thread...
    ...
}

ALTERNATIVE TO EXPLICITLY RUN ADDITIONAL CODE ON MAIN THREAD

async Task MyMethod()
{
    // (This part is same as first code snippet.)
    // "await", so that "additional code" below is not run until this code finishes.
    // "async" is only needed if code in block uses "await".
    await Task.Run( async () =>
    {
        // code that needs to run on a background thread...
        // e.g. long-running logic that does not touch UI.
    });

    // (This part is explicitly run on MainThread.)
    // "async" is only needed if code in block uses "await".
    await MainThread.InvokeOnMainThreadAsync( async () =>
    {
        // code that needs to run on MainThread (affects UI)...
    });
}

huangapple
  • 本文由 发表于 2023年6月8日 22:44:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433036.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定