我正在尝试向我的应用添加基本的回调,以便随着应用通过更新任务的进行,加载状态标签也会更新。但是由于某种原因,在调用一个特定的异步方法后,此后引发的任何事件都不会更新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,但是之后没有成功。
答案 0 :(得分:0)
这是一个UI线程问题当您在背景线程中对async方法进行一些更改时,始终建议您所做的更改将影响UI在MainThread
或UIThread
上完成。现在,您需要做的非常简单。每当您进行应该以任何形式影响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"; });