XAMARIN STATUS DA TASK
Bom dia pessoal, eu acredito que esteja errando em algum problema de Lógica.
Tem como eu Indicar o status de uma Task ?
Eu queria que enquanto eu não sinalizasse que a tarefa estivesse completada, a linha de código que a chamou continuasse aguardando pelo await.
A questão toda, é que não consigo setar esse Status!!!
O que acontece é o seguinte, eu faço um teste de conexão a WebService no servidor , se o teste falhar eu emito uma msg de REPETIR | CANCELAR,
o meu problema mora todo ai, o Dialogo aparece, mas não aguarda eu responder REPETIR ou CANCELAR e já vai para a próxima linha de código,
eu já tentei colocar os metodos como assincronos e usando tarefas, já tentei usar Task.Delay, mas nada funcionou. alguém tem alguma ideia de como contornar isso ?
Tem como eu Indicar o status de uma Task ?
Eu queria que enquanto eu não sinalizasse que a tarefa estivesse completada, a linha de código que a chamou continuasse aguardando pelo await.
A questão toda, é que não consigo setar esse Status!!!
O que acontece é o seguinte, eu faço um teste de conexão a WebService no servidor , se o teste falhar eu emito uma msg de REPETIR | CANCELAR,
o meu problema mora todo ai, o Dialogo aparece, mas não aguarda eu responder REPETIR ou CANCELAR e já vai para a próxima linha de código,
eu já tentei colocar os metodos como assincronos e usando tarefas, já tentei usar Task.Delay, mas nada funcionou. alguém tem alguma ideia de como contornar isso ?
Bom dia!
Você está usando o método DisplayAlert?
Você está usando o método DisplayAlert?
AlertDialog, projeto é Xamarim Android
Como você está fazendo?
Já tentou algo assim?
Já tentou algo assim?
private void AButton_Click(object sender, System.EventArgs e)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder novo = builder.SetMessage([Ô]Deseja repetir a operação?[Ô]).SetPositiveButton([Ô]Repetir[Ô], ClicouDialogo)
.SetNegativeButton([Ô]Cancelar[Ô], ClicouDialogo);
novo.Show();
}
private void ClicouDialogo(object sender, DialogClickEventArgs e)
{
if (e.Which == (int)Android.Content.DialogButtonType.Positive)
{
//repete a acao
}
else
{
//faz o que precisa ser feito pra cancelar
}
}
async void button_Click(object sender, EventArgs e)
{
await Dialogo();
string A = [Ô]Z[Ô];
button.Text = A;
}
private Task Dialogo()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder novo = builder.SetMessage([Ô]Deseja repetir a operação?[Ô]).SetPositiveButton([Ô]Repetir[Ô], ClicouDialogo)
.SetNegativeButton([Ô]Cancelar[Ô], ClicouDialogo);
novo.Show();
return Task.Delay(10000);
}
private async void ClicouDialogo(object sender, DialogClickEventArgs e)
{
if (e.Which == (int)Android.Content.DialogButtonType.Positive)
{
await Dialogo();
}
else
{
//faz o que precisa ser feito pra cancelar
}
}
Até aqui tá tudo lindo, mas tem um porém, como eu faço pra segurar a Task até o momento que o usuário clicar em uma das opções ?
Até onde eu sei, o que você está tentando fazer não é possÃvel..
Mas o resultado do que deseja pode ser reproduzido de outra forma.
Tendo em vista meu código original, basta não colocar nada depois da linha [Ô]novo.Show();[Ô]
Caso você queira que execute uma rotina após a execução da caixa de mensagem, basta colocar dentro do método disparado, uma vez que esse método só vai ser disparado após o clique do botão.
Sendo assim:
private void AButton_Click(object sender, System.EventArgs e)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder novo = builder.SetMessage([Ô]Deseja repetir a operação?[Ô]).SetPositiveButton([Ô]Repetir[Ô], ClicouDialogo)
.SetNegativeButton([Ô]Cancelar[Ô], ClicouDialogo);
novo.Show();
}
private void ClicouDialogo(object sender, DialogClickEventArgs e)
{
if (e.Which == (int)Android.Content.DialogButtonType.Positive)
{
//repete a acao
}
else
{
//faz o que precisa ser feito pra cancelar
}
[txt-color=#e80000]//aqui você coloca o código que precisa executar, depois da caixa de mensagem ser pressionada.
[/txt-color]
}
Mas o resultado do que deseja pode ser reproduzido de outra forma.
Tendo em vista meu código original, basta não colocar nada depois da linha [Ô]novo.Show();[Ô]
Caso você queira que execute uma rotina após a execução da caixa de mensagem, basta colocar dentro do método disparado, uma vez que esse método só vai ser disparado após o clique do botão.
Sendo assim:
private void AButton_Click(object sender, System.EventArgs e)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder novo = builder.SetMessage([Ô]Deseja repetir a operação?[Ô]).SetPositiveButton([Ô]Repetir[Ô], ClicouDialogo)
.SetNegativeButton([Ô]Cancelar[Ô], ClicouDialogo);
novo.Show();
}
private void ClicouDialogo(object sender, DialogClickEventArgs e)
{
if (e.Which == (int)Android.Content.DialogButtonType.Positive)
{
//repete a acao
}
else
{
//faz o que precisa ser feito pra cancelar
}
[txt-color=#e80000]//aqui você coloca o código que precisa executar, depois da caixa de mensagem ser pressionada.
[/txt-color]
}
Olá, Primeiramente quero agradecer por sua atenção, então vamos lá, vou fazer a apresentação do código original necessário.
Talvez seja algum erro de lógica minha. O código tá um pouco redundante, mas é porque estou fazendo muito teste.
Na Activity
Na Classe que realiza a solicitação da WS
Talvez seja algum erro de lógica minha. O código tá um pouco redundante, mas é porque estou fazendo muito teste.
Na Activity
Citação:private async void ButtonObterPessoas()
{
CallWS act = new CallWS(this);
object test = await act.Get<List<Pessoa>>([Ô]pessoa/consulta?todos=true[Ô]);
obj = ((Task<object>)test).Result;
//Restante do Código
}
Na Classe que realiza a solicitação da WS
public class CallWS
{
private string _URL { get; set; }
public bool AguardandoResposta { get; set; }
public static bool? RespostaPing { get; private set; }
private int _TimeOut { get; set; }
private Context contexto { get; set; }
public CallWS(Context Contexto, int TimeOut = 10)
{
_TimeOut = TimeOut;
this.contexto = Contexto;
}
private T ErrorT<T>(string Description, int Code = 0) where T : class, new()
{
T tipo = new T();
MsgError erro = new MsgError() { Codigo = Code, Descricao = [Ô]error: [Ô] + Description };
tipo = (T)Convert.ChangeType(erro, typeof(MsgError));
return tipo;
}
public bool? pingTestWS()
{
TestandoConexao = true;
object ret = this.GetInterno<object>([Ô]teste/pingServiceX[Ô]).Result;
TestandoConexao = false;
if (ret.GetType() == typeof(MsgError))
{
return null;
}
else
{
return true;
}
}
private Task sendPingWS()
{
bool? Resposta = pingTestWS();
if (Resposta == null)
{
RespostaPing = null;
AlertDialog.Builder builder = new AlertDialog.Builder(this.contexto);
builder.SetMessage([Ô]Falha ao comunicar com o servidor![Ô]);
builder.SetCancelable(false);
builder.SetTitle([Ô]Atenção[Ô]);
builder.SetPositiveButton([Ô]Repetir[Ô], delegate { RepetirPergunta(); });
builder.SetNegativeButton([Ô]Cancelar[Ô], delegate { Abortar(); });
builder.Create();
Dialog dialogo = builder.Create();
dialogo.Show();
AguardandoResposta = true;
}
return Task.Delay(10000);
}
private void RepetirPergunta()
{
RespostaPing = null;
this.sendPingWS();
}
private void Abortar()
{
RespostaPing = false;
}
public async Task<object> Get<T>(string URL) where T : class, new()
{
dynamic tipo = new T();
await sendPingWS();
bool? Resposta = pingTestWS();
if (Resposta == null)
{
tipo = this.ErrorT<MsgError>([Ô]Não foi possÃvel conectar ao servidor[Ô]);
}
if (Resposta == true)
{
tipo = GetInterno<T>(URL);
}
return tipo;
}
private async Task<object> GetInterno<T>(string URL) where T : class, new()
{
dynamic tipo = new T();
try
{
string Retorno = await this.GetString<T>(URL);
if (Retorno.Contains([Ô]error:[Ô]))
{
tipo = ErrorT<MsgError>(Retorno);
}
else
{
byte[] bytes = Encoding.Default.GetBytes(Retorno);
object ret = Encoding.UTF8.GetString(bytes);
tipo = JsonConvert.DeserializeObject<T>(ret.ToString());
}
}
catch (System.Exception ex)
{
tipo = ErrorT<MsgError>(ex.Message);
}
return tipo;
}
private Task<string> GetString<T>(string URL, string ToastMessage = [Ô][Ô], Context contexto = null) where T : class, new()
{
string nomeAppIIS = [Ô]celular/[Ô];
if (myGlobal.myConfig.porta == [Ô]4750[Ô]) nomeAppIIS = [Ô][Ô];
string url = string.Format([Ô]http://{0}:{1}/{2}[Ô], myGlobal.myConfig.ipServidor, myGlobal.myConfig.porta, nomeAppIIS);
MsgError RetError = new MsgError();
T tipo = new T();
HttpClient client = new HttpClient();
try
{
client.Timeout = new TimeSpan(0, 0, _TimeOut);
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue([Ô]application/json[Ô]));
HttpResponseMessage X = client.GetAsync([Ô]api/[Ô] + URL).Result;
if (X.IsSuccessStatusCode)
{
Task<string> A = X.Content.ReadAsStringAsync();
return A;
}
else
{
return Task.FromResult<string>([Ô]error: (BAD) Solicitação ao servidor falhou.[Ô]);
}
}
catch (System.Exception ex)
{
return Task.FromResult<string>([Ô]error: [Ô] + ex.Message);
}
}
}
Resolvido, já já posto o código!
Na Activity
private async void obterPessoas()
{
object obj = await new Misc.CallWS(this).Get<List<Pessoa>>([Ô]pessoa/consulta?Todos=true[Ô]);
if (obj.GetType() == typeof(Misc.MsgError))
{
//Mensagem de erro
}
else
{
List<Pessoa> pessoas = (List<Pessoa>)obj;
}
}
public class MsgError
{
public int Codigo { get; set; }
public string Descricao { get; set; }
}
Classe para requisições na WebService
public class CallWS
{
private string _URL { get; set; }
public bool AguardandoResposta { get; set; }
public bool? RespostaPing { get; private set; }
private int _TimeOut { get; set; }
private Context contexto { get; set; }
private bool TestandoConexao = false;
public CallWS(Context Contexto, int TimeOut = 10)
{
_TimeOut = TimeOut;
this.contexto = Contexto;
}
private T ErrorT<T>(string Description, int Code = 0) where T : class, new()
{
T tipo = new T();
MsgError erro = new MsgError() { Codigo = Code, Descricao = [Ô]error: [Ô] + Description };
tipo = (T)Convert.ChangeType(erro, typeof(MsgError));
return tipo;
}
public bool? pingTestWS()
{
TestandoConexao = true;
object ret = this.GetInterno<object>([Ô]teste/pingService[Ô]).Result;
TestandoConexao = false;
if (ret.GetType() == typeof(MsgError))
{
return null;
}
else
{
return true;
}
}
private Task sendPingWS()
{
bool? Resposta = null;
if (AguardandoResposta == false)
{
Resposta = pingTestWS();
if (Resposta == null)
{
RespostaPing = null;
AlertDialog.Builder builder = new AlertDialog.Builder(this.contexto);
builder.SetMessage([Ô]Falha ao comunicar com o servidor![Ô]);
builder.SetCancelable(false);
builder.SetTitle([Ô]Atenção[Ô]);
builder.SetPositiveButton([Ô]Repetir[Ô], delegate { RepetirPergunta(); });
builder.SetNegativeButton([Ô]Cancelar[Ô], delegate { Abortar(); } );
builder.Create();
Dialog dialogo = builder.Create();
dialogo.Show();
builder.Dispose();
AguardandoResposta = true;
}
else
{
AguardandoResposta = false;
}
}
if (Resposta == null)
{
return Task.Delay(3000);
}
else
{
RespostaPing = true;
return Task.Delay(1);
}
}
private void RepetirPergunta()
{
RespostaPing = null;
AguardandoResposta = false;
this.sendPingWS();
}
private void Abortar()
{
RespostaPing = false;
}
public bool Perguntou { get; set; }
public async Task<object> Get<T>(string URL) where T : class, new()
{
dynamic tipo = new T();
while (RespostaPing == null)
{
await sendPingWS();
}
if (RespostaPing == true)
{
tipo = (T)GetInterno<T>(URL).Result;
}
else
{
tipo = this.ErrorT<MsgError>([Ô]Não foi possÃvel conectar ao servidor[Ô]);
}
return tipo;
}
private async Task<object> GetInterno<T>(string URL) where T : class, new()
{
dynamic tipo = new T();
try
{
string Retorno = this.GetString<T>(URL).Result;
if (Retorno.Contains([Ô]error:[Ô]))
{
tipo = ErrorT<MsgError>(Retorno);
}
else
{
byte[] bytes = Encoding.Default.GetBytes(Retorno);
object ret = Encoding.UTF8.GetString(bytes);
tipo = JsonConvert.DeserializeObject<T>(ret.ToString());
}
}
catch (System.Exception ex)
{
tipo = ErrorT<MsgError>(ex.Message);
}
return tipo;
}
private Task<string> GetString<T>(string URL, string ToastMessage = [Ô][Ô], Context contexto = null) where T : class, new()
{
string nomeAppIIS = [Ô]celular/[Ô];
if (myGlobal.myConfig.porta == [Ô]4750[Ô]) nomeAppIIS = [Ô][Ô];
string url = string.Format([Ô]http://{0}:{1}/{2}[Ô], myGlobal.myConfig.ipServidor, myGlobal.myConfig.porta, nomeAppIIS);
MsgError RetError = new MsgError();
T tipo = new T();
HttpClient client = new HttpClient();
try
{
client.Timeout = new TimeSpan(0, 0, _TimeOut);
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue([Ô]application/json[Ô]));
HttpResponseMessage X = client.GetAsync([Ô]api/[Ô] + URL).Result;
if (X.IsSuccessStatusCode)
{
Task<string> A = X.Content.ReadAsStringAsync();
return A;
}
else
{
return Task.FromResult<string>([Ô]error: (BAD) Solicitação ao servidor falhou.[Ô]);
}
}
catch (System.Exception ex)
{
return Task.FromResult<string>([Ô]error: [Ô] + ex.Message);
}
}
}
DS2T
Muito obrigado por sua atenção, tudo resolvido.
O código ficou acima.
Muito obrigado por sua atenção, tudo resolvido.
O código ficou acima.
Tópico encerrado , respostas não são mais permitidas