首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Xamarins表单中的异步调用

Xamarins表单中的异步调用
EN

Stack Overflow用户
提问于 2016-07-23 00:52:39
回答 1查看 198关注 0票数 0

我正在使用Xamarin Forms C#在安卓系统中向SQLite导入数据,但我遇到了问题。

为了进行数据导入,我使用了自己开发的API,每个表都有一个链接,在本例中,我导入了5个表,每个表大约有1.000条记录,我需要进行5个调用(call Table1API,call Table2API,call Table3API,call Table4API,call Table5API)

这是正确的工作,但在DDMS中显示此错误,"I/Choreographer(1273):跳过259帧!应用程序可能在其主线程上做了太多工作“,应用程序崩溃。

我做错了什么?

请访问帮助链接:

方法和按钮单击事件:https://1drv.ms/u/s!AlRdq6Nx4CD6g4ouw1F1KJzmnfx5zg

我使用API的方法:

代码语言:javascript
运行
复制
public async Task<string> ConsumeRestAPI(string url, string tkn)
{
    url += "?" + tkn;
    string retString = string.Empty;

    try
    {
        using (var client = new HttpClient())
        {
            var result = await client.GetAsync(url);
            retString = await result.Content.ReadAsStringAsync();
        }
    }
    catch (Exception ex)
    {
        retString = ex.Message + "\n\nErro ao tentar se conectar com o servidor.";
    }

    return retString;
}

方法和按钮单击事件:

代码语言:javascript
运行
复制
private async Task AsyncTaskTPRE(string pSYNC_DescTabela, string pSYNC_NomeTabela)
    {
        string pUrl = string.Empty;
        string content = string.Empty;
        string jsonMsgError = string.Empty;
        int qtdReg = 0;

        ServiceWrapper sw = new ServiceWrapper();
        JArray jsonArray = null;

        if (!actLoading.IsRunning)
            actLoading.IsRunning = true;
        lblTitulo.Text = "Conectando à API...";

        pUrl = pAPIURL + "TabelaPrecoAPI.aspx";
        content = await sw.ConsumeRestAPI(pUrl, pAPITKN);

        if (!ErroRetornoJSON(content, pSYNC_DescTabela, out jsonMsgError))
        {
            #region Importação tbTPRE

            content = sw.Html2JSON(content);
            jsonArray = JArray.Parse(content);
            qtdReg = 1;

            foreach (var itemJSON in jsonArray)
            {
                PreencherTPRE(itemJSON);

                lblTitulo.FontSize = 12;
                lblTitulo.HorizontalOptions = LayoutOptions.Start;
                lblTitulo.VerticalOptions = LayoutOptions.Start;

                lblTitulo.Text = "Importando " + "\"" + pSYNC_DescTabela + "\"...\n"
                    + " (Registro " + qtdReg.ToString() + " de " + jsonArray.Count() + " importado(s))";
                await Task.Delay(10);

                TPRE TPRE_Atual = pTPRE.GetTPRE(objTPRE.TPRE_Codigo, objTPRE.TPRE_SQEM_Id);
                if (TPRE_Atual == null)
                {
                    pTPRE.Insert(objTPRE);
                    if (pTPRE.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao importar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objTPRE.TPRE_Id + "\n"
                            + "Erro: " + pTPRE.MsgError, "OK");
                        break;
                    }
                }
                else
                {
                    pTPRE.Update(objTPRE);
                    if (pTPRE.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao atualizar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objTPRE.TPRE_Id + "\n"
                            + "Erro: " + pTPRE.MsgError, "OK");
                        break;
                    }
                }

                qtdReg++;
            }

            #endregion

            #region Insert/Update tbSYNC

            SYNC objSYNC = pSYNC.GetSYNC(pSYNC_NomeTabela);
            if (objSYNC == null)
            {
                objSYNC = new SYNC()
                {
                    SYNC_NomeTabela = pSYNC_NomeTabela,
                    SYNC_DescTabela = pSYNC_DescTabela,
                    SYNC_DataImportSync = DateTime.Now,
                    SYNC_DataExportSync = null,
                    CreatedBy = string.Empty,
                    CreatedOn = DateTime.Now,
                    UpdatedBy = string.Empty,
                    UpdatedOn = DateTime.Now
                };

                pSYNC.Insert(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao incluir registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }
            else
            {
                objSYNC.SYNC_DataImportSync = DateTime.Now;
                objSYNC.UpdatedBy = string.Empty;
                objSYNC.UpdatedOn = DateTime.Now;

                pSYNC.Update(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao atualizar registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }

            #endregion
        }
        else
        {
            await DisplayAlert("Atenção", jsonMsgError, "OK");
        }
    }

    private async Task AsyncTaskITTP(string pSYNC_DescTabela, string pSYNC_NomeTabela)
    {
        string pUrl = string.Empty;
        string content = string.Empty;
        string jsonMsgError = string.Empty;
        int qtdReg = 0;

        ServiceWrapper sw = new ServiceWrapper();
        JArray jsonArray = null;

        if (!actLoading.IsRunning)
            actLoading.IsRunning = true;

        lblTitulo.Text = "Conectando à API...";
        pUrl = pAPIURL + "ItensTabelaPrecoAPI.aspx";
        content = await sw.ConsumeRestAPI(pUrl, pAPITKN);

        if (!ErroRetornoJSON(content, pSYNC_DescTabela, out jsonMsgError))
        {
            #region Importação tbITTP

            content = sw.Html2JSON(content);
            jsonArray = JArray.Parse(content);
            qtdReg = 1;

            foreach (var ITTPjson in jsonArray)
            {
                PreencherITTP(ITTPjson);

                lblTitulo.FontSize = 12;
                lblTitulo.HorizontalOptions = LayoutOptions.Start;
                lblTitulo.VerticalOptions = LayoutOptions.Start;

                lblTitulo.Text = "Importando " + "\"" + pSYNC_DescTabela + "\"...\n"
                    + " (Registro " + qtdReg.ToString() + " de " + jsonArray.Count() + " importado(s))";
                await Task.Delay(10);

                ITTP ITTP_Atual = pITTP.GetITTP(objITTP.ITTP_Id);
                if (ITTP_Atual == null)
                {
                    pITTP.InsertWithChildren(objITTP);
                    if (pITTP.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao importar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objITTP.ITTP_Id + "\n"
                            + "Erro: " + pITTP.MsgError, "OK");
                        break;
                    }
                }
                else
                {
                    pITTP.UpdateWithChildren(objITTP);
                    if (pITTP.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao atualizar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objITTP.ITTP_Id + "\n"
                            + "Erro: " + pITTP.MsgError, "OK");
                        break;
                    }
                }

                qtdReg++;
            }

            #endregion

            #region Insert/Update tbSYNC

            SYNC objSYNC = pSYNC.GetSYNC(pSYNC_NomeTabela);
            if (objSYNC == null)
            {
                objSYNC = new SYNC()
                {
                    SYNC_NomeTabela = pSYNC_NomeTabela,
                    SYNC_DescTabela = pSYNC_DescTabela,
                    SYNC_DataImportSync = DateTime.Now,
                    SYNC_DataExportSync = null,
                    CreatedBy = string.Empty,
                    CreatedOn = DateTime.Now,
                    UpdatedBy = string.Empty,
                    UpdatedOn = DateTime.Now
                };

                pSYNC.Insert(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao incluir registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }
            else
            {
                objSYNC.SYNC_DataImportSync = DateTime.Now;
                objSYNC.UpdatedBy = string.Empty;
                objSYNC.UpdatedOn = DateTime.Now;

                pSYNC.Update(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao atualizar registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }

            #endregion
        }
        else
        {
            await DisplayAlert("Atenção", jsonMsgError, "OK");
        }
    }

    private async Task AsyncTaskPLPG(string pSYNC_DescTabela, string pSYNC_NomeTabela)
    {
        string pUrl = string.Empty;
        string content = string.Empty;
        string jsonMsgError = string.Empty;
        int qtdReg = 0;

        ServiceWrapper sw = new ServiceWrapper();
        JArray jsonArray = null;

        if (!actLoading.IsRunning)
            actLoading.IsRunning = true;

        lblTitulo.Text = "Conectando à API...";
        pUrl = pAPIURL + "PlanoPagamentoAPI.aspx";
        content = await sw.ConsumeRestAPI(pUrl, pAPITKN);

        if (!ErroRetornoJSON(content, pSYNC_DescTabela, out jsonMsgError))
        {
            #region Importação tbPLPG

            content = sw.Html2JSON(content);
            jsonArray = JArray.Parse(content);
            qtdReg = 1;

            foreach (var PLPGjson in jsonArray)
            {
                PreencherPLPG(PLPGjson);

                lblTitulo.FontSize = 12;
                lblTitulo.HorizontalOptions = LayoutOptions.Start;
                lblTitulo.VerticalOptions = LayoutOptions.Start;

                lblTitulo.Text = "Importando " + "\"" + pSYNC_DescTabela + "\"...\n"
                    + " (Registro " + qtdReg.ToString() + " de " + jsonArray.Count() + " importado(s))";
                await Task.Delay(10);

                PLPG PLPG_Atual = pPLPG.GetPLPG(objPLPG.PLPG_Id);
                if (PLPG_Atual == null)
                {
                    pPLPG.Insert(objPLPG);
                    if (pPLPG.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao importar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objPLPG.PLPG_Id + "\n"
                            + "Erro: " + pPLPG.MsgError, "OK");
                        break;
                    }
                }
                else
                {
                    pPLPG.Update(objPLPG);
                    if (pPLPG.HasError)
                    {
                        await DisplayAlert("Error", "Erro ao atualizar registro da tabela " + pSYNC_DescTabela + "!\n"
                            + "ID do Registro: " + objPLPG.PLPG_Id + "\n"
                            + "Erro: " + pPLPG.MsgError, "OK");
                        break;
                    }
                }

                qtdReg++;
            }

            #endregion

            #region Insert/Update tbSYNC

            SYNC objSYNC = pSYNC.GetSYNC(pSYNC_NomeTabela);
            if (objSYNC == null)
            {
                objSYNC = new SYNC()
                {
                    SYNC_NomeTabela = pSYNC_NomeTabela,
                    SYNC_DescTabela = pSYNC_DescTabela,
                    SYNC_DataImportSync = DateTime.Now,
                    SYNC_DataExportSync = null,
                    CreatedBy = string.Empty,
                    CreatedOn = DateTime.Now,
                    UpdatedBy = string.Empty,
                    UpdatedOn = DateTime.Now
                };

                pSYNC.Insert(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao incluir registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }
            else
            {
                objSYNC.SYNC_DataImportSync = DateTime.Now;
                objSYNC.UpdatedBy = string.Empty;
                objSYNC.UpdatedOn = DateTime.Now;

                pSYNC.Update(objSYNC);
                if (pSYNC.HasError)
                {
                    await DisplayAlert("Error", "Erro ao atualizar registro na tabela de sincronização!\n" + pSYNC.MsgError, "OK");
                }
            }

            #endregion
        }
        else
        {
            await DisplayAlert("Atenção", jsonMsgError, "OK");
        }
    }

private async void BtnImport_Clicked(object sender, EventArgs e)
{
        List<SYNC> listSYNC = lvwTabelas.ItemsSource.Cast<SYNC>().ToList();
        bool confirmacaoProcessamento = false;

        PopularStatusConexao();

        #region Validação de Campos/Parâmetros

        var regSelecionado = listSYNC.Where(s => s.SYNC_IsToggled).Any();
        if (!regSelecionado)
        {
            await DisplayAlert("Atenção", "Selecione pelo menos uma tabela para importar!", "OK");
        }
        else if (!pConnStatus)
        {
            await DisplayAlert("Atenção", "Sem conexão com internet!\nPara prosseguir com o processamento é necessário que esteja conectado em alguma rede.", "OK");
        }
        else if (!pConnWifiStatus)
        {
            var confirm = await DisplayAlert("Confirmação", "Para prosseguir com o processo de importação, recomendamos "
                + "que esteja conectado em uma rede WiFi.\n\nDeseja prosseguir?", "Sim", "Não");

            confirmacaoProcessamento = confirm;
        }
        else if (pAPIURL == string.Empty)
        {
            await DisplayAlert("Atenção", "Parâmetro \"URL\" inválido!\nVerifique o parâmetro na parametrização da API.", "OK");
        }
        else if (pAPITKN == string.Empty)
        {
            await DisplayAlert("Atenção", "Parâmetro \"Token\" inválido!\nVerifique o parâmetro na parametrização da API.", "OK");
        }
        else
        {
            var confirm = await DisplayAlert("Confirmação", "Para prosseguir com o processo de importação, recomendamos "
                + "que esteja conectado em uma rede WiFi, atualmente você possui essa conexão.\n\nDeseja prosseguir?", "Sim", "Não");

            confirmacaoProcessamento = confirm;
        }

        #endregion

        #region Operação

        if (confirmacaoProcessamento)
        {
            lvwTabelas.IsEnabled = false;
            btnImport.IsEnabled = false;
            swtSelecionarTodos.IsVisible = false;

            listSYNC = listSYNC.Where(s => s.SYNC_IsToggled).ToList();
            foreach (var item in listSYNC)
            {
                //int pPEFJ_Codigo = 0;
                //int pPEFJ_SQEM_Id = 0;

                #region Importação de Tabelas

                switch (item.SYNC_NomeTabela)
                {
                    #region tbPEFJ - Pessoa Física/Jurídica

                    case "tbPEFJ":
                        await AsyncTaskPEFJ(item.SYNC_DescTabela, item.SYNC_NomeTabela);

                        break;

                    #endregion

                    #region tbPROD - Produtos

                    case "tbPROD":
                        //qtdReg = 1;

                        //lblTitulo.FontSize = 15;
                        //lblTitulo.HorizontalOptions = LayoutOptions.Start;
                        //lblTitulo.Text = "Importando " + "\"" + item.SYNC_DescTabela + "\"...";
                        //await Task.Delay(1000);

                        break;

                    #endregion

                    //

                    #region tbTPRE - Tabela de Preço

                    case "tbTPRE":
                        await AsyncTaskTPRE(item.SYNC_DescTabela, item.SYNC_NomeTabela);

                        break;

                    #endregion

                    #region tbITTP - Itens da Tabela de Preço

                    case "tbITTP":
                        await AsyncTaskITTP(item.SYNC_DescTabela, item.SYNC_NomeTabela);

                        break;

                    #endregion

                    #region tbPLPG - Plano de Pagamento

                    case "tbPLPG":
                        await AsyncTaskPLPG(item.SYNC_DescTabela, item.SYNC_NomeTabela);

                        break;

                    #endregion

                    #region tbFOPG - Forma de Pagamento

                    case "tbFOPG":
                        await AsyncTaskFOPG(item.SYNC_DescTabela, item.SYNC_NomeTabela);

                        break;

                    #endregion

                    //

                    #region tbPEDI - Pedidos

                    case "tbPEDI":
                        //lblTitulo.FontSize = 15;
                        //lblTitulo.HorizontalOptions = LayoutOptions.Start;
                        //lblTitulo.Text = "Importando " + "\"" + item.SYNC_DescTabela + "\"...";
                        //await Task.Delay(1000);

                        break;

                    #endregion

                    #region tbITPD - Itens do Pedido

                    case "tbITPD":
                        //lblTitulo.FontSize = 15;
                        //lblTitulo.HorizontalOptions = LayoutOptions.Start;
                        //lblTitulo.Text = "Importando " + "\"" + item.SYNC_DescTabela + "\"...";
                        //await Task.Delay(1000);

                        break;

                    #endregion

                    default:
                        break;
                }

                #endregion
            }

            swtSelecionarTodos.IsVisible = true;
            actLoading.IsRunning = false;

            //if (!erroProc)
            //    await DisplayAlert("Aviso", "Importação realizada com sucesso!", "OK");

            lblTitulo.FontSize = 22;
            lblTitulo.Text = "Importação de Tabelas";
            lblTitulo.HorizontalOptions = LayoutOptions.Center;

            lvwTabelas.IsEnabled = true;
            btnImport.IsEnabled = true;

            Popular_lvwTabelas();
            PopularStatusConexao();
        }

        #endregion
    }
EN

回答 1

Stack Overflow用户

发布于 2016-07-23 08:01:56

当你点击那个按钮时,看起来你实际上并没有启动一个新的线程。如果是这样,那么所有的工作都是在主线程上完成的,因此可能会导致错误。要启动一个新线程,您确实需要调用Task.Run(...)或使用其他一些实际启动新线程的API。正如代码所示,除非我错过了它,否则你永远不会启动一个新线程。你确实在等待一些其他的异步操作,比如DisplayAlert,但是因为你从来没有使用过Task.ConfigureAwait(false),所以你总是被返回到主线程。如果在调用您等待的第一个异步方法时,执行以下操作(在AsyncTaskTPRE方法中):

代码语言:javascript
运行
复制
content = await sw.ConsumeRestAPI(pUrl, pAPITKN).ConfigureAwait(false);

当该方法返回时,您将不再处于UI/主线程上。如果没有ConfigureAwait(false),当该方法返回时,您将返回到主线程,因为ConfigureAwait(...)的缺省值为true。

请参阅MS关于使用异步和等待的指南:https://msdn.microsoft.com/en-us/library/mt674882.aspx

在标题为“线程”的部分中,它说了以下内容:

等待async和

关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不在自己的线程上运行。该方法在当前同步上下文上运行,并且仅当该方法处于活动状态时才使用线程上的时间。您可以使用Task.Run将受CPU限制的工作转移到后台线程,但是后台线程对正在等待结果变得可用的进程没有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38531711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档