none
Problema Thread vb.net RRS feed

  • Pregunta

  • Dispongo de una pagina .aspx donde tengo un calendario que al pulsar sobre un día, se invoca un método que quiero que muestre dos update:panel, el primero de ellos lo tiene que mostrar al momento y el segundo es la respuesta que me devuelve googleFlights al realizar una consulta, como dicha consulta tarda cierto tiempo en realizarse, no quiero esperar a ella para tener que mostrar el primer panel, sino que nada más pulsar en el calendario el primer panel se muestre y el segundo pues se muestre cuando ya tenga la respuesta, así de esta forma el usuario puede seguir usando la web sin tener que esperar a la consulta.

    Para ello tengo una prueba que consiste en llamar a este metodo:

    protected sub QueryFlights1()
         Thread.Sleep(5000)
        Solutionida.Text = "hola"
        Solutionvuelta.Text = "adios"
        MaxSearch.Text = "ya"
    End Sub

    Para llamar a este método desde otro hilo tengo lo siguiente:

    Dim Flight As New Thread(AddressOf QueryFlights1)
    Flight.Start()

    El problema es que no se me muestra el segundo panel y me da el error:

    system.argumentexception- ya existe una entrada con la misma clave

    miércoles, 13 de julio de 2016 11:55

Respuestas

  • Sigues teniendo el error de creer que el servidor está conectado con el cliente durante la llamada asíncrona. Dentro del QueryFlights estás cambiando la propiedad .Text de los controles de la página, pero esa clase en la que estás cambiando el .Text no está conectada con la página en ese momento.

    Además, un GET a Default.aspx/QueryFlights1 no llamará al método QuryFlights1 dentro del aspx, salvo que hagas maravillas con los Handlers en el servidor para mapearlo así.

    Además, en el $.ajax no has puesto ninguna retrollamada para pintar en la pantalla los resultados cuando se reciban del servidor.

    Si quieres complicarte lo mínimo posible, te recomendaría usar un load de jquery sobre el contenedor donde quieras presentar los datos, que es lo que te resultará más simple:

    $(function () {
                $('#Calendar1').click(function () {
                    $('#sitio').load('MiPagina.aspx');
                });
            });

    Con ese código, el control que tiene ID="sitio" es el lugar en el que se presentarán los resultados (lo que antes habías puesto dentro de un UpdatePanel, que ahora estará (por ejemplo) dentro de un <div id="sitio">.

    Y 'MiPagina.aspx' es una página "pequeña" que solo tiene que tener dentro lo necesario para generar el html que quieras visualizar dentro del div (es decir, tienes que recortarle todas las cabeceras y pies de página, que ya existen dentro de la página destinataria en la que vas a incrustar esos resultados).

    jueves, 14 de julio de 2016 18:48

Todas las respuestas

  • No puedes hacer lo que quieres con un Thread en el lado servidor. Tienes que hacerlo con una llamada asíncrona en el lado cliente. Recuerda que en una aplicación web la iniciativa siempre tiene que partir del cliente. El cliente envía una petición al servidor, el cual hace sus cálculos, genera HTML, lo envía al cliente, y termina, destruye la clase, y cierra la conexión. Si al cabo de un rato se recibiese un resultado por parte de un Hilo lanzado previamente, para entonces ya no se podría enviar al cliente porque la conexión con éste ya no existe.

    Hay un par de soluciones. Una es mantener una conexión persistente desde el cliente al servidor usando WebSockets o mecanismos equivalentes (o una librería tal como SignalR). Esto permitiría que un hilo en el servidor vaya enviando resultados al cliente cuando se reciban.

    Otra es programar Ajax con javascript desde el cliente. Una llamada asíncrona en Ajax puede pedir que se ejecuta QueryFlights en el servidor, y presentar los resultados cuando se reciban sin bloquear la pantalla mientras tanto.

    miércoles, 13 de julio de 2016 20:46
  • Muchas gracias por tu ayuda.

    Estoy tratando de hacerlo con ajax pero sigo igual de atascado, a continuación te pongo el código.

    Este es el elemento calendario que cuando selecciono una fecha quiero que se ejecute el otro metodo:

    <ECalendar:EventCalendar ID="Calendar1" runat="server" BackColor="White" BorderColor="Silver"
                                                            Font-Names="Verdana" OnDayRender="CalendarDRender"
                                                            Font-Size="9pt" ForeColor="Black" FirstDayOfWeek="Sunday" NextMonthText="Next &gt;" PrevMonthText="&lt; Prev" SelectionMode="Day"
                                                            ShowGridLines="True" NextPrevFormat="FullMonth"
                                                            ShowDescriptionAsToolTip="True" BorderStyle="Solid" EventDateColumnName="" EventDescriptionColumnName="" EventHeaderColumnName="" OnSelectionChanged="Calendar1_SelectionChanged" >
                                                            <SelectedDayStyle BackColor="White" ForeColor="Black" />
                                                            <SelectorStyle BorderColor="#404040" BorderStyle="Solid" />
                                                            <DayStyle HorizontalAlign="Left" VerticalAlign="Top" Wrap="True" />
                                                            <OtherMonthDayStyle ForeColor="#999999" />
                                                            <NextPrevStyle Font-Size="8pt" ForeColor="#333333" Font-Bold="True" VerticalAlign="Bottom" />
                                                            <DayHeaderStyle BorderWidth="1px" Font-Bold="True" Font-Size="8pt" />
                                                            <TitleStyle BackColor="White" Font-Bold="True"
                                                                Font-Size="12pt" ForeColor="#333399" HorizontalAlign="Center" VerticalAlign="Middle" />
                                                        </ECalendar:EventCalendar>

    por otra parte como hago la peticion ajax:

    $(function () {
                $('#Calendar1').click(function () {
                    $.ajax({
                        type: "GET",
                        url: "Default.aspx/QueryFlights1"                                                         
                    });
                });
            });

    y el metodo QueryFligths1

    <WebMethod>
        Public Sub QueryFlights1()
            Solutionida.Text = "hola"
            Solutionvuelta.Text = "adios"
            MaxSearch.Text = "ya"
        End Sub

    Si me pudieses decir donde tengo el error y que estoy haciendo mal se lo agradeceria.

    jueves, 14 de julio de 2016 15:45
  • Sigues teniendo el error de creer que el servidor está conectado con el cliente durante la llamada asíncrona. Dentro del QueryFlights estás cambiando la propiedad .Text de los controles de la página, pero esa clase en la que estás cambiando el .Text no está conectada con la página en ese momento.

    Además, un GET a Default.aspx/QueryFlights1 no llamará al método QuryFlights1 dentro del aspx, salvo que hagas maravillas con los Handlers en el servidor para mapearlo así.

    Además, en el $.ajax no has puesto ninguna retrollamada para pintar en la pantalla los resultados cuando se reciban del servidor.

    Si quieres complicarte lo mínimo posible, te recomendaría usar un load de jquery sobre el contenedor donde quieras presentar los datos, que es lo que te resultará más simple:

    $(function () {
                $('#Calendar1').click(function () {
                    $('#sitio').load('MiPagina.aspx');
                });
            });

    Con ese código, el control que tiene ID="sitio" es el lugar en el que se presentarán los resultados (lo que antes habías puesto dentro de un UpdatePanel, que ahora estará (por ejemplo) dentro de un <div id="sitio">.

    Y 'MiPagina.aspx' es una página "pequeña" que solo tiene que tener dentro lo necesario para generar el html que quieras visualizar dentro del div (es decir, tienes que recortarle todas las cabeceras y pies de página, que ya existen dentro de la página destinataria en la que vas a incrustar esos resultados).

    jueves, 14 de julio de 2016 18:48
  • Perdona mi insistencia pero ahora  con Ajax en vb.net tengo problemas al hacer la llamada me la realiza más de una vez,¿sabes si hay algún "bug" respecto a esto? ¿y como poder solucionarlo?

    Código javascript de como realizo la llamada al pulsar un botón:

    $(function () {
                $('#btprueba').click(function () {
                    $.ajax({                    
                        type: "POST",
                        url: "MiPagina.aspx?IDCircuit=2450",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json"                    
                });
                    $('#sitio').load('MiPagina.aspx');
                });
            });

    Código de la página "MiPagina.aspx":

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not IsPostBack Then
                Dim idcircuit As Integer
                If Not Request.QueryString("IDCircuit") Is Nothing Then
                    idcircuit = CInt(Request.QueryString("IDCircuit"))
                End If
                QueryFlights(idcircuit)
            End If
    
        End Sub
    El problema es que al realizarse más de una llamada el idcircuit en el método "QueryFligths" me da erros ya que lo coge como 0 en las posteriores llamadas

    lunes, 18 de julio de 2016 12:23