c# - 为什么不调用 AsyncTask 中的 OnProgressUpdate?

标签 c# android xamarin android-asynctask

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

我面临的问题是 OnProgressUpdate 方法仅在我正在使用的处理后台任务的 AsyncTask 对象中被调用一次。这是我的类(class):

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); 如果我为 sleep 使用较小的值,OnProgressUpdate 将不会在第一次之后被调用。我之所以选择 500,是因为有了这个值,OnProgressUpdate 会被正确调用,并且屏幕上的进度条会更新。

为什么我必须在一定的时间间隔内让线程休眠?我希望进度条实时更新,而不是每半秒更新一次。

最佳答案

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

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

关于c# - 为什么不调用 AsyncTask 中的 OnProgressUpdate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46091304/

相关文章:

Android Jetpack Compose - 自定义图像的 float 操作按钮

c# - Visual Studio 中的 Xamarin iOS——调试语句被记录两次

c# - 创建 SQLite 表 Xamarin 表单

c# - 如何访问正在运行的应用程序的应用程序 list ?

c# - 从 Windows 服务启动 Windows 应用程序

c# - 无法声明 ArrayList

android - 如何在不使用 orderBy 两次的情况下构建查询来检索有序列表?

Android - 在不同的 Activity 中使用一个 DatePicker fragment

xaml - Xamarin FontAwesome 无法从背后的代码中工作

c# - 对象 xml 反序列化问题?