Error

27/11/2004 - 20:33 por Alberto | Informe spam
Hola
Me esta surgiendo este error:
"La acción que se realiza en este control se está llamando desde el
subproceso erróneo. Debe calcular las referencias al subproceso correcto
utilizando Control.Invoke o Control.BeginInvoke para realizar esta acción."

alguien sabe de que puede ser?


Gracias

Preguntas similare

Leer las respuestas

#6 Alberto
29/11/2004 - 00:34 | Informe spam
Gracias por todo.
Pero.. todavia no logro entenderlo. Ese ejemplo que me pasaste esta todo en
el mismo objeto y diferentes Threads. Como lo lograria con mi caso?

=(


"Miguel Angel Campos" escribió en el
mensaje news:
A ver si te vale este ejemplo:
http://samples.gotdotnet.com/quicks...lling.aspx

Practicamente es lo mismo que has realizado desde el principio para hacer
las llamadas a los Socket de forma asincrona. Estableces un procedimiento
o
evento a donde te deben llamar, le pasas a Invoke o BeginInvoke este
procedimiento o evento, y será .NET el encargado de llamarlo desde el
Thread
correspondiente.

Un Saludo.

"Alberto" escribió en el mensaje
news:
Y cual seria lasolucion para esto ?

"Miguel Angel Campos" escribió en


el
mensaje news:
> El problema es que .NET está haciendo el Multithread por tí, al
> utilizar
> las
> llamadas asincronas, es .NET el que realiza la llamada desde un Thread


del
> ThreadPool que esté disponible.
>
> Prueba a realizar lo siguiente:
> - Desde el mismo Winform muestra el valor devuelto por
> System.Threading.Thread.CurrentThread.GetHashCode()
> - Desde el evento generado muestra el mismo valor.
>
> Los dos valores serán distintos.
> Ese mismo problema se produce cuando realizas una llamada a un


WebService
> de
> forma asincrona e intentas establecer los datos devueltos en un control
> gráfico, por ejemplo un Dataset en un DataGrid.
>
> Un Saludo.
>
> "Alberto" escribió en el mensaje
> news:
>> No estoy haciendo Multithread.
>> Tengo un WinForm, con un boton, y un treeview. Cree una clase que


trabaja
>> con sockets asincronica, y al recibir un dato genero un evento, para
> obtener
>> los datos desde el WinForm. El error me lo da cuando se genera el


evento
>> y
>> yo desde el winform recorro una collecion del objeto (con los datos
>> recibidos) y quiero insertar esos objetos en un TreeView :(


pero...
> si
>> en vez de insertarlo en un control hago un
>> MessageBox.Show(objectodecoleccion.Proiedad) me hace el MessageBox
>> por
> cada
>> elemento sin generar error.
>> Alguna idea de este caso?
>>
>>
>>
>> "Miguel Angel Campos" escribió


en
> el
>> mensaje news:
>> > Me imagino que estás haciendo una aplicación MultiThread, y estas
> llamando
>> > a
>> > un función o propiedad de un control gráfico desde un determinado
> Thread.
>> > Si es esto lo que estas haciendo tienes que tener en cuenta que sólo


se
>> > puede llamar a las propiedades y métodos de un control, desde el


mismo
>> > Thread desde el cual se creo discho control.
>> > Los métodos Invoke y BeginInvoke te permiten realizar las llamadas
>> > desde
>> > otros Thread distintos, siendo .NET el encargado de realizar la


llamada
>> > desde el Thread correcto.
>> >
>> > He encontrado este ejemplo:
>> > http://www.codeguru.com/Csharp/Csha...php/c5851/
>> >
>> > Un Saludo.
>> >
>> > "Alberto" escribió en el mensaje
>> > news:%
>> >> Hola
>> >> Me esta surgiendo este error:
>> >> "La acción que se realiza en este control se está llamando desde el
>> >> subproceso erróneo. Debe calcular las referencias al subproceso
> correcto
>> >> utilizando Control.Invoke o Control.BeginInvoke para realizar esta
>> > acción."
>> >>
>> >> alguien sabe de que puede ser?
>> >>
>> >>
>> >> Gracias
>> >>
>> >>
>> >
>> >
>>
>>
>
>






Respuesta Responder a este mensaje
#7 Miguel Angel Campos
29/11/2004 - 21:27 | Informe spam
Aqui no paramos hasta que no soluciones el problema, pero esta vez creo que
será la definitiva.
Pasos:
- Tu tienes un Winform(Form1) que tiene un EventHandler
implementado(ClaseSocket1_EndData) que está subscripto al evento(EndData) de
la clase que encapsula el Socket (la llamamos ClaseSocket1).
ClaseSocket1.EndData += new EventHandler(Form1.ClaseSocket1_EndData)
Nota: no se el tipo de EventHandler que estas utilizando, suponemos uno
generico.
- Cuando terminas de recibir los datos desde el Socket, se produce un evento
asincrono en la clase ClaseSocket1, que verifica si tienes alguien subscrito
a su evento, y dispara el evento.
if (EndData != null)
EndData(this, new EventArgs());
- Se llama al procedimiento ClaseSocket1_EndData del WinForm donde deseas
capturar dicho evento, y es aqui donde te da el error. (En este
procedimiento es donde lees los datos y actualizas el TreeView)
- Pues crea otro EventHandler, si quieres privado, que tiene como parametros
los mismos que el otro EventHandler(ClaseSocket1_EndData) que ya tienes
implementado en el WinForm, por ejemplo:
private void RefreshData(object sender, EventArgs e)
- Dentro de este procedimiento metes el código que tenias antes en el
procedimiento ClaseSocket1_EndData.
- Y Dentro del procedimiento ClaseSocket1_EndData, pones lo siguiente:
Form1.Inkoke(new EventHandler(RefreshData))

Esto ultimo lo que va a realizar es asegurarse que llama al método
RefreshData, pero desde el Thread adecuado.

Si tienes algún problema, no dudes en comentarme lo que sea, y si quieres me
mandas las dos clases, Socket y WinForm.

Un Saludo.

"Alberto" escribió en el mensaje
news:
Gracias por todo.
Pero.. todavia no logro entenderlo. Ese ejemplo que me pasaste esta todo


en
el mismo objeto y diferentes Threads. Como lo lograria con mi caso?

=(


"Miguel Angel Campos" escribió en


el
mensaje news:
>A ver si te vale este ejemplo:
>


http://samples.gotdotnet.com/quicks...lling.aspx
>
> Practicamente es lo mismo que has realizado desde el principio para


hacer
> las llamadas a los Socket de forma asincrona. Estableces un


procedimiento
> o
> evento a donde te deben llamar, le pasas a Invoke o BeginInvoke este
> procedimiento o evento, y será .NET el encargado de llamarlo desde el
> Thread
> correspondiente.
>
> Un Saludo.
>
> "Alberto" escribió en el mensaje
> news:
>> Y cual seria lasolucion para esto ?
>>
>> "Miguel Angel Campos" escribió


en
> el
>> mensaje news:
>> > El problema es que .NET está haciendo el Multithread por tí, al
>> > utilizar
>> > las
>> > llamadas asincronas, es .NET el que realiza la llamada desde un


Thread
> del
>> > ThreadPool que esté disponible.
>> >
>> > Prueba a realizar lo siguiente:
>> > - Desde el mismo Winform muestra el valor devuelto por
>> > System.Threading.Thread.CurrentThread.GetHashCode()
>> > - Desde el evento generado muestra el mismo valor.
>> >
>> > Los dos valores serán distintos.
>> > Ese mismo problema se produce cuando realizas una llamada a un
> WebService
>> > de
>> > forma asincrona e intentas establecer los datos devueltos en un


control
>> > gráfico, por ejemplo un Dataset en un DataGrid.
>> >
>> > Un Saludo.
>> >
>> > "Alberto" escribió en el mensaje
>> > news:
>> >> No estoy haciendo Multithread.
>> >> Tengo un WinForm, con un boton, y un treeview. Cree una clase que
> trabaja
>> >> con sockets asincronica, y al recibir un dato genero un evento, para
>> > obtener
>> >> los datos desde el WinForm. El error me lo da cuando se genera el
> evento
>> >> y
>> >> yo desde el winform recorro una collecion del objeto (con los datos
>> >> recibidos) y quiero insertar esos objetos en un TreeView :(
> pero...
>> > si
>> >> en vez de insertarlo en un control hago un
>> >> MessageBox.Show(objectodecoleccion.Proiedad) me hace el MessageBox
>> >> por
>> > cada
>> >> elemento sin generar error.
>> >> Alguna idea de este caso?
>> >>
>> >>
>> >>
>> >> "Miguel Angel Campos"


escribió
> en
>> > el
>> >> mensaje news:
>> >> > Me imagino que estás haciendo una aplicación MultiThread, y estas
>> > llamando
>> >> > a
>> >> > un función o propiedad de un control gráfico desde un determinado
>> > Thread.
>> >> > Si es esto lo que estas haciendo tienes que tener en cuenta que


sólo
> se
>> >> > puede llamar a las propiedades y métodos de un control, desde el
> mismo
>> >> > Thread desde el cual se creo discho control.
>> >> > Los métodos Invoke y BeginInvoke te permiten realizar las llamadas
>> >> > desde
>> >> > otros Thread distintos, siendo .NET el encargado de realizar la
> llamada
>> >> > desde el Thread correcto.
>> >> >
>> >> > He encontrado este ejemplo:
>> >> > http://www.codeguru.com/Csharp/Csha...php/c5851/
>> >> >
>> >> > Un Saludo.
>> >> >
>> >> > "Alberto" escribió en el mensaje
>> >> > news:%
>> >> >> Hola
>> >> >> Me esta surgiendo este error:
>> >> >> "La acción que se realiza en este control se está llamando desde


el
>> >> >> subproceso erróneo. Debe calcular las referencias al subproceso
>> > correcto
>> >> >> utilizando Control.Invoke o Control.BeginInvoke para realizar


esta
>> >> > acción."
>> >> >>
>> >> >> alguien sabe de que puede ser?
>> >> >>
>> >> >>
>> >> >> Gracias
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >
>>
>>
>
>


Respuesta Responder a este mensaje
#8 Alberto
30/11/2004 - 02:08 | Informe spam
Muchicimas, Muchicimas gracias por todo!! :)
Y no me voy a despedir sin hacerte la ultima pregunta :P No hay forma de
hacer algo generico en la clase del socket? Para que el que utilice esta
libreria no haga falta que haga tanto lio?

Muchas Gracias otra vez! =)

"Miguel Angel Campos" escribió en el
mensaje news:ei6$
Aqui no paramos hasta que no soluciones el problema, pero esta vez creo
que
será la definitiva.
Pasos:
- Tu tienes un Winform(Form1) que tiene un EventHandler
implementado(ClaseSocket1_EndData) que está subscripto al evento(EndData)
de
la clase que encapsula el Socket (la llamamos ClaseSocket1).
ClaseSocket1.EndData += new EventHandler(Form1.ClaseSocket1_EndData)
Nota: no se el tipo de EventHandler que estas utilizando, suponemos uno
generico.
- Cuando terminas de recibir los datos desde el Socket, se produce un
evento
asincrono en la clase ClaseSocket1, que verifica si tienes alguien
subscrito
a su evento, y dispara el evento.
if (EndData != null)
EndData(this, new EventArgs());
- Se llama al procedimiento ClaseSocket1_EndData del WinForm donde deseas
capturar dicho evento, y es aqui donde te da el error. (En este
procedimiento es donde lees los datos y actualizas el TreeView)
- Pues crea otro EventHandler, si quieres privado, que tiene como
parametros
los mismos que el otro EventHandler(ClaseSocket1_EndData) que ya tienes
implementado en el WinForm, por ejemplo:
private void RefreshData(object sender, EventArgs e)
- Dentro de este procedimiento metes el código que tenias antes en el
procedimiento ClaseSocket1_EndData.
- Y Dentro del procedimiento ClaseSocket1_EndData, pones lo siguiente:
Form1.Inkoke(new EventHandler(RefreshData))

Esto ultimo lo que va a realizar es asegurarse que llama al método
RefreshData, pero desde el Thread adecuado.

Si tienes algún problema, no dudes en comentarme lo que sea, y si quieres
me
mandas las dos clases, Socket y WinForm.

Un Saludo.

"Alberto" escribió en el mensaje
news:
Gracias por todo.
Pero.. todavia no logro entenderlo. Ese ejemplo que me pasaste esta todo


en
el mismo objeto y diferentes Threads. Como lo lograria con mi caso?

=(


"Miguel Angel Campos" escribió en


el
mensaje news:
>A ver si te vale este ejemplo:
>


http://samples.gotdotnet.com/quicks...lling.aspx
>
> Practicamente es lo mismo que has realizado desde el principio para


hacer
> las llamadas a los Socket de forma asincrona. Estableces un


procedimiento
> o
> evento a donde te deben llamar, le pasas a Invoke o BeginInvoke este
> procedimiento o evento, y será .NET el encargado de llamarlo desde el
> Thread
> correspondiente.
>
> Un Saludo.
>
> "Alberto" escribió en el mensaje
> news:
>> Y cual seria lasolucion para esto ?
>>
>> "Miguel Angel Campos" escribió


en
> el
>> mensaje news:
>> > El problema es que .NET está haciendo el Multithread por tí, al
>> > utilizar
>> > las
>> > llamadas asincronas, es .NET el que realiza la llamada desde un


Thread
> del
>> > ThreadPool que esté disponible.
>> >
>> > Prueba a realizar lo siguiente:
>> > - Desde el mismo Winform muestra el valor devuelto por
>> > System.Threading.Thread.CurrentThread.GetHashCode()
>> > - Desde el evento generado muestra el mismo valor.
>> >
>> > Los dos valores serán distintos.
>> > Ese mismo problema se produce cuando realizas una llamada a un
> WebService
>> > de
>> > forma asincrona e intentas establecer los datos devueltos en un


control
>> > gráfico, por ejemplo un Dataset en un DataGrid.
>> >
>> > Un Saludo.
>> >
>> > "Alberto" escribió en el mensaje
>> > news:
>> >> No estoy haciendo Multithread.
>> >> Tengo un WinForm, con un boton, y un treeview. Cree una clase que
> trabaja
>> >> con sockets asincronica, y al recibir un dato genero un evento,
>> >> para
>> > obtener
>> >> los datos desde el WinForm. El error me lo da cuando se genera el
> evento
>> >> y
>> >> yo desde el winform recorro una collecion del objeto (con los datos
>> >> recibidos) y quiero insertar esos objetos en un TreeView :(
> pero...
>> > si
>> >> en vez de insertarlo en un control hago un
>> >> MessageBox.Show(objectodecoleccion.Proiedad) me hace el MessageBox
>> >> por
>> > cada
>> >> elemento sin generar error.
>> >> Alguna idea de este caso?
>> >>
>> >>
>> >>
>> >> "Miguel Angel Campos"


escribió
> en
>> > el
>> >> mensaje news:
>> >> > Me imagino que estás haciendo una aplicación MultiThread, y estas
>> > llamando
>> >> > a
>> >> > un función o propiedad de un control gráfico desde un determinado
>> > Thread.
>> >> > Si es esto lo que estas haciendo tienes que tener en cuenta que


sólo
> se
>> >> > puede llamar a las propiedades y métodos de un control, desde el
> mismo
>> >> > Thread desde el cual se creo discho control.
>> >> > Los métodos Invoke y BeginInvoke te permiten realizar las
>> >> > llamadas
>> >> > desde
>> >> > otros Thread distintos, siendo .NET el encargado de realizar la
> llamada
>> >> > desde el Thread correcto.
>> >> >
>> >> > He encontrado este ejemplo:
>> >> > http://www.codeguru.com/Csharp/Csha...php/c5851/
>> >> >
>> >> > Un Saludo.
>> >> >
>> >> > "Alberto" escribió en el mensaje
>> >> > news:%
>> >> >> Hola
>> >> >> Me esta surgiendo este error:
>> >> >> "La acción que se realiza en este control se está llamando desde


el
>> >> >> subproceso erróneo. Debe calcular las referencias al subproceso
>> > correcto
>> >> >> utilizando Control.Invoke o Control.BeginInvoke para realizar


esta
>> >> > acción."
>> >> >>
>> >> >> alguien sabe de que puede ser?
>> >> >>
>> >> >>
>> >> >> Gracias
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >
>>
>>
>
>






Respuesta Responder a este mensaje
#9 Miguel Angel Campos
01/12/2004 - 20:38 | Informe spam
Entiendo muy bien tu preocupación, pero analiza bien el problema que has
tenido. El problema viene causado por el entorno de aquel que lo ha
utilizado, en este caso una aplicación Windows (WinForm), que no soporta muy
bien un entorno multithreading. Si trasladas la solución del problema a tu
clase, que por otro lado lo podrías hacer sin problemas, harías que esta
clase sólo funcionara para un entorno concreto, en lugar de tenerla
preparada para cualquier tipo de entorno (multithreading, en este caso). No
se que hace exactamente tu componente, pero imagina que lo quiere utilizar
alguien desde un determinado thread, de un conjunto de varios que tiene en
ejecución, y no utiliza interfaz de usuario.

Si quieres puedes crear una propiedad de tipo System.Windows.Forms.Control,
y dentro de tu clases metes la lógica que has realizado hasta ahora,
llamando al Invoke de este Control. No se si me he explicado.

Te comento que la programación multi-hilo es algo compleja hasta que le
coges el truco, pero es cuestión de tiempo.

Un Saludo, y hasta pronto.

"Alberto" escribió en el mensaje
news:
Muchicimas, Muchicimas gracias por todo!! :)
Y no me voy a despedir sin hacerte la ultima pregunta :P No hay forma de
hacer algo generico en la clase del socket? Para que el que utilice esta
libreria no haga falta que haga tanto lio?

Muchas Gracias otra vez! =)

"Miguel Angel Campos" escribió en


el
mensaje news:ei6$
> Aqui no paramos hasta que no soluciones el problema, pero esta vez creo
> que
> será la definitiva.
> Pasos:
> - Tu tienes un Winform(Form1) que tiene un EventHandler
> implementado(ClaseSocket1_EndData) que está subscripto al


evento(EndData)
> de
> la clase que encapsula el Socket (la llamamos ClaseSocket1).
> ClaseSocket1.EndData += new EventHandler(Form1.ClaseSocket1_EndData)
> Nota: no se el tipo de EventHandler que estas utilizando, suponemos uno
> generico.
> - Cuando terminas de recibir los datos desde el Socket, se produce un
> evento
> asincrono en la clase ClaseSocket1, que verifica si tienes alguien
> subscrito
> a su evento, y dispara el evento.
> if (EndData != null)
> EndData(this, new EventArgs());
> - Se llama al procedimiento ClaseSocket1_EndData del WinForm donde


deseas
> capturar dicho evento, y es aqui donde te da el error. (En este
> procedimiento es donde lees los datos y actualizas el TreeView)
> - Pues crea otro EventHandler, si quieres privado, que tiene como
> parametros
> los mismos que el otro EventHandler(ClaseSocket1_EndData) que ya tienes
> implementado en el WinForm, por ejemplo:
> private void RefreshData(object sender, EventArgs e)
> - Dentro de este procedimiento metes el código que tenias antes en el
> procedimiento ClaseSocket1_EndData.
> - Y Dentro del procedimiento ClaseSocket1_EndData, pones lo siguiente:
> Form1.Inkoke(new EventHandler(RefreshData))
>
> Esto ultimo lo que va a realizar es asegurarse que llama al método
> RefreshData, pero desde el Thread adecuado.
>
> Si tienes algún problema, no dudes en comentarme lo que sea, y si


quieres
> me
> mandas las dos clases, Socket y WinForm.
>
> Un Saludo.
>
> "Alberto" escribió en el mensaje
> news:
>> Gracias por todo.
>> Pero.. todavia no logro entenderlo. Ese ejemplo que me pasaste esta


todo
> en
>> el mismo objeto y diferentes Threads. Como lo lograria con mi caso?
>>
>> =(
>>
>>
>> "Miguel Angel Campos" escribió


en
> el
>> mensaje news:
>> >A ver si te vale este ejemplo:
>> >
>


http://samples.gotdotnet.com/quicks...lling.aspx
>> >
>> > Practicamente es lo mismo que has realizado desde el principio para
> hacer
>> > las llamadas a los Socket de forma asincrona. Estableces un
> procedimiento
>> > o
>> > evento a donde te deben llamar, le pasas a Invoke o BeginInvoke este
>> > procedimiento o evento, y será .NET el encargado de llamarlo desde el
>> > Thread
>> > correspondiente.
>> >
>> > Un Saludo.
>> >
>> > "Alberto" escribió en el mensaje
>> > news:
>> >> Y cual seria lasolucion para esto ?
>> >>
>> >> "Miguel Angel Campos"


escribió
> en
>> > el
>> >> mensaje news:
>> >> > El problema es que .NET está haciendo el Multithread por tí, al
>> >> > utilizar
>> >> > las
>> >> > llamadas asincronas, es .NET el que realiza la llamada desde un
> Thread
>> > del
>> >> > ThreadPool que esté disponible.
>> >> >
>> >> > Prueba a realizar lo siguiente:
>> >> > - Desde el mismo Winform muestra el valor devuelto por
>> >> > System.Threading.Thread.CurrentThread.GetHashCode()
>> >> > - Desde el evento generado muestra el mismo valor.
>> >> >
>> >> > Los dos valores serán distintos.
>> >> > Ese mismo problema se produce cuando realizas una llamada a un
>> > WebService
>> >> > de
>> >> > forma asincrona e intentas establecer los datos devueltos en un
> control
>> >> > gráfico, por ejemplo un Dataset en un DataGrid.
>> >> >
>> >> > Un Saludo.
>> >> >
>> >> > "Alberto" escribió en el mensaje
>> >> > news:
>> >> >> No estoy haciendo Multithread.
>> >> >> Tengo un WinForm, con un boton, y un treeview. Cree una clase que
>> > trabaja
>> >> >> con sockets asincronica, y al recibir un dato genero un evento,
>> >> >> para
>> >> > obtener
>> >> >> los datos desde el WinForm. El error me lo da cuando se genera el
>> > evento
>> >> >> y
>> >> >> yo desde el winform recorro una collecion del objeto (con los


datos
>> >> >> recibidos) y quiero insertar esos objetos en un TreeView :(
>> > pero...
>> >> > si
>> >> >> en vez de insertarlo en un control hago un
>> >> >> MessageBox.Show(objectodecoleccion.Proiedad) me hace el


MessageBox
>> >> >> por
>> >> > cada
>> >> >> elemento sin generar error.
>> >> >> Alguna idea de este caso?
>> >> >>
>> >> >>
>> >> >>
>> >> >> "Miguel Angel Campos"
> escribió
>> > en
>> >> > el
>> >> >> mensaje news:
>> >> >> > Me imagino que estás haciendo una aplicación MultiThread, y


estas
>> >> > llamando
>> >> >> > a
>> >> >> > un función o propiedad de un control gráfico desde un


determinado
>> >> > Thread.
>> >> >> > Si es esto lo que estas haciendo tienes que tener en cuenta que
> sólo
>> > se
>> >> >> > puede llamar a las propiedades y métodos de un control, desde


el
>> > mismo
>> >> >> > Thread desde el cual se creo discho control.
>> >> >> > Los métodos Invoke y BeginInvoke te permiten realizar las
>> >> >> > llamadas
>> >> >> > desde
>> >> >> > otros Thread distintos, siendo .NET el encargado de realizar la
>> > llamada
>> >> >> > desde el Thread correcto.
>> >> >> >
>> >> >> > He encontrado este ejemplo:
>> >> >> >


http://www.codeguru.com/Csharp/Csha...php/c5851/
>> >> >> >
>> >> >> > Un Saludo.
>> >> >> >
>> >> >> > "Alberto" escribió en el mensaje
>> >> >> > news:%
>> >> >> >> Hola
>> >> >> >> Me esta surgiendo este error:
>> >> >> >> "La acción que se realiza en este control se está llamando


desde
> el
>> >> >> >> subproceso erróneo. Debe calcular las referencias al


subproceso
>> >> > correcto
>> >> >> >> utilizando Control.Invoke o Control.BeginInvoke para realizar
> esta
>> >> >> > acción."
>> >> >> >>
>> >> >> >> alguien sabe de que puede ser?
>> >> >> >>
>> >> >> >>
>> >> >> >> Gracias
>> >> >> >>
>> >> >> >>
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >
>>
>>
>
>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida