英文:
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)...
});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论