为什么不调用AsyncTask中的OnProgressUpdate?

时间:2017-09-07 08:15:07

标签: c# android xamarin android-asynctask

然而,使用Xamarin.Android,我不认为这是我的问题背后的原因。

我面临的问题是OnProgressUpdate方法只能在AsyncTask对象中使用句柄后台任务调用一次。这是我的班级:

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);
    }
}

我设法将问题缩小到这条线:Java.Lang.Thread.Sleep(500); 如果我使用较小的值进行睡眠,OnProgressUpdate将在第一次调用后不被调用。我登陆500,因为有了这个值,OnProgressUpdate会被正确调用,并且progressBar会在屏幕上更新。

我有必要以一定的间隔睡眠线程吗?我希望progressBar能够实时更新,而不是每半秒更新一次。

1 个答案:

答案 0 :(得分:3)

Task方法中的DoInBackground线程中运行不报告其进度的内容没有任何意义。

当调用DoInBackground时,您不在UI线程上而是在后台线程中,您可以通过检查Looper.MainLooper.IsCurrentThread的值进行检查,因此不需要使用Task.Run

因此,一旦进入DoInBackground,您的DB Inflater将会执行一系列步骤,创建数据库,创建表,索引等等。然后使用数据等加载每个表...您可以自行决定已发生的进度并将其发布(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());
    }
}