异步功能后引发的任何事件均无法正确更新UI

时间:2019-07-09 10:20:57

标签: c# asynchronous events xamarin.android

我正在尝试向我的应用添加基本的回调,以便随着应用通过更新任务的进行,加载状态标签也会更新。但是由于某种原因,在调用一个特定的异步方法后,此后引发的任何事件都不会更新UI。

我尝试了各种配置等待设置,并仔细查看了异步方法本身,但找不到任何明显错误的东西。

public async Task RefreshTable<T>() where T : class, IEntity
    {
        try
        {
            OnContentUpdateProgressChange(this, new MessageEventArgs($"RefreshTable before {typeof(T).Name}"));
            var tableJsonData = await ApiService.GetEntityListAsync<T>();
            OnContentUpdateProgressChange(this, new MessageEventArgs($"RefreshTable after {typeof(T).Name}"));
            await LoadTableData(Set<T>(), tableJsonData);
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
        }
    }

public async Task<List<T>> GetEntityListAsync<T>(string url = null) where T : class
    {
        if (string.IsNullOrEmpty(url))
        {
            url = typeof(T).Name.Replace("_", "");
        }
        try
        {
            string entityList = null;
            HttpResponseMessage response = await Client.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                entityList = await response.Content.ReadAsStringAsync();
                var backupFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), typeof(T).Name);
                using (var writer = File.CreateText(backupFile))
                {
                    await writer.WriteLineAsync(entityList.ToString());
                }
            }
            return await Task.Factory.StartNew(() => JsonConvert.DeserializeObject<List<T>>(entityList));
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
            throw;
        }
    }


    private void DB_OnContentUpdateProgressChange(object sender, library.EventArguments.MessageEventArgs e)
    {
        lblLoadingState.Text = e.Message;
    }

在调用GetEntityListAsync之前引发的事件成功更新了UI,但是之后没有成功。

1 个答案:

答案 0 :(得分:0)

根据我的理解,

这是一个UI线程问题当您在背景线程中对async方法进行一些更改时,始终建议您所做的更改将影响UI在MainThreadUIThread上完成。现在,您需要做的非常简单。每当您进行应该以任何形式影响UI的更改时,都应在UI线程上进行更改。

我想做的是在一个方法中对所有UI进行更改,然后我希望有一个Activity类的基础版本,该基类具有帮助者,让我检查它是否是MainThread并相应地使用方法。

  • 添加一个从AppCompatActivity继承的Activity,然后向其中添加以下内容。

     public abstract class BaseActivity : AppCompatActivity
     {
       protected override void OnCreate(Bundle savedInstanceState)
       {
           base.OnCreate(savedInstanceState);
       }
    
        public bool IsMainThread => Build.VERSION.SdkInt >= BuildVersionCodes.M
        ? Looper.MainLooper.IsCurrentThread
        : Looper.MyLooper() == Looper.MainLooper;
    
        public void RunOnMainThread(Action action)
        {
          if (IsMainThread) action();
          else RunOnUiThread(action);
        } 
    
    }
    
  • 然后进行UI更改,例如:

    RunOnMainThread(() => { LabelDoSomething.Text = "New Text"; });