C# 为什么';调用异步任务中的t OnProgressUpdate?
然而,使用Xamarin.Android,我不认为这是我的问题背后的原因 我面临的问题是,在我正在处理后台任务的AsyncTask对象中,OnProgressUpdate方法只被调用一次。这是我的班级:C# 为什么';调用异步任务中的t OnProgressUpdate?,c#,android,xamarin,android-asynctask,C#,Android,Xamarin,Android Asynctask,然而,使用Xamarin.Android,我不认为这是我的问题背后的原因 我面临的问题是,在我正在处理后台任务的AsyncTask对象中,OnProgressUpdate方法只被调用一次。这是我的班级: public class DBInflater : AsyncTask { private int progress; private ProgressBar progressBar; public DatabaseInflater(ProgressBar progre
public class DBInflater : AsyncTask
{
private int progress;
private ProgressBar progressBar;
public DatabaseInflater(ProgressBar progressBar)
{
this.progressBar = progressBar;
}
protected override void OnPreExecute()
{
base.OnPreExecute();
}
protected override Java.Lang.Object DoInBackground(params Java.Lang.Object[] @params)
{
System.Threading.Tasks.Task.Run([some heavy task]);
while (progress < 100)
{
Java.Lang.Thread.Sleep(500);
PublishProgress(progress);
progress += 1;
}
return true;
}
protected override void OnProgressUpdate(params Java.Lang.Object[] values)
{
progressBar.Progress = progress;
}
protected override void OnPostExecute(Java.Lang.Object result)
{
base.OnPostExecute(result);
}
}
公共类db充气器:异步任务
{
私人投资进展;
私人ProgressBar ProgressBar;
公共数据库充气器(ProgressBar ProgressBar)
{
this.progressBar=progressBar;
}
受保护的覆盖无效OnPreExecute()
{
base.OnPreExecute();
}
受保护的重写Java.Lang.Object DoInBackground(params Java.Lang.Object[]@params)
{
System.Threading.Tasks.Task.Run([一些繁重的任务]);
而(进度<100)
{
Java.Lang.Thread.Sleep(500);
出版进度(progress);
进度+=1;
}
返回true;
}
受保护的重写void OnProgressUpdate(params Java.Lang.Object[]值)
{
progressBar.Progress=进度;
}
受保护的重写void OnPostExecute(Java.Lang.Object结果)
{
base.OnPostExecute(结果);
}
}
我已经设法将问题缩小到这一行:Java.Lang.Thread.Sleep(500);
如果我对sleep使用较小的值,则在第一次之后不会调用OnProgressUpdate。我在500上着陆,因为有了这个值,OnProgressUpdate被正确调用,progressBar在屏幕上更新
有没有一个原因,为什么我必须睡眠线程在一定的间隔?我希望progressBar实时更新,而不是每半秒钟更新一次。在
DoInBackground
方法中的Task
线程中运行某个不报告其进度的内容是没有意义的
调用DoInBackground
时,您不是在UI线程上,而是在后台线程上,您可以通过检查Looper.MainLooper.IsCurrentThread
的值进行检查,因此不必使用Task.Run
因此,在DoInBackground
中,您的DB充气机将执行一系列步骤,创建DB、创建表、索引等。。然后在每个表中加载数据等。。。由您决定已发生的进展量并发布(PublishProgress
)
在这个例子中,我有三个步骤,在完成每个步骤后,竞争增加了33%
public class DBInflaterAsyncTask : AsyncTask
{
protected override Object DoInBackground(params Object[] @params)
{
// You are not on the UI thread
Task.Delay(1000); // create db
PublishProgress(new Object[] { 33 });
Task.Delay(1000); // create tables
PublishProgress(new Object[] { 66 });
Task.Delay(1000); // load table data
PublishProgress(new Object[] { 99 });
return null;
}
protected override void OnProgressUpdate(params Object[] values)
{
// You are on the UI thread
Log.Debug("SomeTag", values[0].ToString());
}
}
1.你的进步是个谎言。2.“如果我使用较小的睡眠值,OnProgressUpdate在第一次之后不会被调用。”-如何确定?换句话说,[一些繁重的任务]
应该PublishProgress
进入doInBackground
线程。我应该澄清,[some heavy task]是我从共享库调用的任务。然而,我不认为这是问题的核心。while循环让我感到悲伤。我在代码示例中遗漏了一些报告传入值[0]值的日志输出。如果我穿线。睡觉(这个答案可能是正确方法的最佳体现,当你没有一个有形的整数值作为进度基准时。因此,设置你自己的进度点是最好的选择。请参考我在我的问题下面的评论。我的问题不是在后台处理什么,也不是在做什么。)e实际进度计算。这似乎是我调用PublishProgress的速率。@hellaandrew调用OnProgressUpdate
将您放回UI线程,并更新进度位置将其发送到消息队列,等等。如果您更快地发布事件,则UI线程可以跟上,您将获得一个“长操作”问题(您可以在手机的开发选项中启用可视长操作闪存)。如果您记录OnProgressUpdate
调用,除非您的异步任务引发异常并终止,或者您正在阻止/锁定后台线程,否则将无法调用这些调用。@hellaandrew仅供参考:在另一个线程进行某些处理时,在50秒以上任意更新进度条不会对用户产生太大影响用户也不会实际显示该任务是否已完成处理,您不妨将样式设置为“不确定”和“等待”
atask
result