【问题标题】:UIKITThreadAccessException from await Task.Run with a try-catch-finally block来自 await Task.Run 的 UIKITThreadAccessException 带有 try-catch-finally 块
【发布时间】:2023-03-17 11:45:01
【问题描述】:

我有办法

public async Task doSomething()

在方法里面我有代码:

ShowSpinner();      

await System.Threading.Tasks.Task.Run(() =>
{
    try
    {
        getValue = value();
    }
    catch(Exception ex)
    {
    }
    finally
    {
        HideSpinner();
    }
    });

ShowSpinner()HideSpinner() 只是简单的叠加层,以防止用户与屏幕交互并显示一个旋转的轮子来指示加载。

我收到错误:

UIKit 一致性错误:您正在调用的 UIKit 方法只能 从 UI 线程调用。

我知道这是因为HideSpinner()。我怎样才能解决这个一致性错误?

【问题讨论】:

  • 重复的问题与 WPF 相关,而不是 Xamarin。相同的一般概念,不同的答案。在 Xamarin Forms 中,您需要使用 Device.BeginInvokeOnMainThread(),在 Xarmarin iOS 中,您将使用 InvokeOnMainThread() 来强制 UI 更新在 UI 线程上运行。

标签: c# asynchronous xamarin try-catch


【解决方案1】:

您可以在这里做两件事,首选方法是在 try finally 块中等待您的任务,第二种不太首选的方法是将您的 HideSpinner(); 包装在 RunOnUiThread 中。

首选

ShowSpinner();
try
{    
    var val = await Task.Run(() => "foo");
    // for a little added performance, 
    // if val isn't being marshalled to the UI
    // you can use .ConfigureAwait(false);
    // var val = await Task.Run(() => "foo").ConfigureAwait(false);
}
catch { /* gulp */}
finally { HideSpinner(); }

不太喜欢

ShowSpinner();
await Task.Run(() =>
{
    try
    {
        var val = "value";
    }
    catch { /* gulp */ }
    finally
    {
        InvokeOnMainThread(() =>
        {
            HideSpinner();
        });

    }
});

【讨论】:

    猜你喜欢
    • 2011-06-01
    • 2018-11-07
    • 2012-03-06
    • 2015-09-05
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 2014-11-27
    • 2013-12-16
    相关资源
    最近更新 更多