none
limitar el tiempo de ejecucion de un metodo RRS feed

  • Pregunta

  • Hola,

    Tengo una aplicación en una PDA que tiene que conectarse por gprs a un web service y retornar un DataSet con los datos solicitados. Cuando no tiene conexion gprs debe obtener los datos de la base de datos local(.sdf)

    Mi problema es que cuando no tiene conexion se queda pegada por unos 40 segundos o mas antes de ir a buscar en la base local.

    lo que tengo de codigo es algo asi:

    try

    {

           miDataSet = servicioWEb.ObenerDatos(idProducto);

    }

    catch

    {

             miDataSet = ObenerDatosLocales(idProducto);

    }

    Como puedo limitar el tiempo de espera para que no se quede tanto rato intentado conecatr con el servicio web antes de buscar en la BD local?

     

    Saludos

    Muchas gracias

    Carlos

    lunes, 4 de octubre de 2010 16:53

Todas las respuestas

  • Buenas Carlosvpa.

     

    Efectivamente tarda esos cuarenta segundos aproximadamente en comprobar si puede conectar, porque realmente intenta hacer la conexión y hasta que esta no recibe timeout no queda tranquila.

     

    Opciones hay varias.

     

    Si la ip del servicio es fija, podrías hacer un ping, que supongo que no tardará tanto como los cuarenta segundos en responderte.

     

    Otra opción más efectiva es comprobar si la radio de GPRS se encuentra activa, puedes ver un ejemplo de su uso aquí . He aprovechado y la he subido a mi blog.

     

    En resumidas cuentas,  la clase que te he dejado permite comprobar si la conexión de internet móvil está disponible en ese momento y además la activa.

     

    Espero que te sea de ayuda.

     

    Saludos

    lunes, 4 de octubre de 2010 22:58
  • Hola jmmontero,

    Gracias por responder. Ahora no puedo entrar al link que pusiste (bloqueado por websense)pero luego lo veo y te cuento.

    Si la ip del servicio es fija, podrías hacer un ping, que supongo que no tardará tanto como los cuarenta segundos en responderte.

    Como se hace un ping desde la PDA al server? o desde la aplicaion de la PDA al server?

     

    Muchas gracias

    Saludos

     

    martes, 5 de octubre de 2010 16:49
  • Buenos dias Carlosvpa

     

    Tenia otro ejemplo para hacer ping mas facilillo pero necesitaba de un espacio de nombres que no se encuentra en Windows Mobile. De todas maneras tenia otra forma para hacerlo.

     

    Aqui lo tienes. Esta en Vb .Net. Lo he probado dentro de un emulador y se me ha quedado algo tonto, pero es porque no lo tendre con red o algo, pruebalo en un dispositivo real y me comentas que tal te ha ido.

    Aun asi, mediante la posibilidad de GPRS me parece mucho mejor.


    Imports System.Net
    Imports System.Net.Sockets
    Imports System.Runtime.InteropServices
    Namespace Utilidades
        Public Class Ping
            ''' <summary>
            ''' Lanza cuatro pings a la dirección seleccionada y comprueba si los paquetes han sidos resueltos correctamente o no
            ''' </summary>
            ''' <param name="direccion">
            ''' La dirección ip o dirección web a la que se le realiza ping
            ''' </param>
            ''' <returns>
            ''' Devuelve true en caso de que el ping sea correcto y false si es incorrecto
            ''' </returns>
            ''' <remarks></remarks>
            Public Function do_ping(ByVal direccion As String) As Boolean
                Dim resultado As Integer = 0
                Dim ok As Integer = 0
                For i As Integer = 0 To 4
                    resultado = pingear(direccion)
                    If (resultado >= 0) And (resultado <= 150) Then
                        ok = ok + 1
                    Else
                        'Hacer algo..
                    End If
                Next
                If (ok >= 4) Then
                    Return True
                Else
                    Return False
                End If
            End Function
            ''' <summary>
            ''' Realiza un ping a una direccion ip o web
            ''' </summary>
            ''' <param name="direccion">
            ''' La ip o direccion web
            ''' </param>
            ''' <returns>
            ''' Devuelve el tiempo de respuesta en milisegundos o si es -1 es inaccesible
            ''' En caso de que de un valor 0 la dirreción es incorrecta
            ''' </returns>
            ''' <remarks></remarks>
            Private Function pingear(ByVal direccion As String) As Integer
                Dim Packet As New APing.CPing
                Packet.HostName = Trim(direccion)
                If Packet.HostName = "" Then
                    Return -1
                Else
                    If Packet.Open Then
                        If (timeout(Packet.Ping) = True) Then
                            Return -1
                        Else
                            Return Packet.Ping
                        End If
                        Packet.Close()
                    End If
                End If
            End Function
            Private Function timeout(ByVal time As Integer) As Boolean
                If (time > 150) Then
                    Return True
                Else
                    Return False
                End If
            End Function
        End Class

        Namespace APing
            Structure Angel_Ping
    #Region "VARIABLES"
                Dim Data() As Byte
                Dim Type_Message As Byte
                Dim SubCode_type As Byte
                Dim Complement_CheckSum As UInt16
                Dim Identifier As UInt16
                Dim SequenceNumber As UInt16
    #End Region
    #Region "Metodos"
                Public Sub Initialize(ByVal type As Byte, ByVal subCode As Byte, ByVal payload() As Byte)
                    Dim Buffer_IcmpPacket() As Byte
                    Dim CksumBuffer() As UInt16
                    Dim IcmpHeaderBufferIndex As Int32 = 0
                    Dim Index As Integer
                    Me.Type_Message = type
                    Me.SubCode_type = subCode
                    Complement_CheckSum = UInt16.Parse("0")
                    Identifier = UInt16.Parse("45")
                    SequenceNumber = UInt16.Parse("0")
                    Data = payload
                    Buffer_IcmpPacket = Serialize()
                    ReDim CksumBuffer((Buffer_IcmpPacket.Length() \ 2) - 1)
                    For Index = 0 To (CksumBuffer.Length() - 1)
                        CksumBuffer(Index) = BitConverter.ToUInt16(Buffer_IcmpPacket, IcmpHeaderBufferIndex)
                        IcmpHeaderBufferIndex += 2
                    Next Index
                    Complement_CheckSum = MCheckSum.Calculate(CksumBuffer, CksumBuffer.Length())
                End Sub
                Public Function Size() As Integer
                    Return (8 + Data.Length())
                End Function
                Public Function Serialize() As Byte()
                    Dim Buffer() As Byte
                    Dim B_Seq() As Byte = BitConverter.GetBytes(SequenceNumber)
                    Dim B_Cksum() As Byte = BitConverter.GetBytes(Complement_CheckSum)
                    Dim B_Id() As Byte = BitConverter.GetBytes(Identifier)
                    Dim Index As Int32 = 0
                    ReDim Buffer(Size() - 1)
                    Buffer(0) = Type_Message
                    Buffer(1) = SubCode_type
                    Index += 2
                    Array.Copy(B_Cksum, 0, Buffer, Index, 2) : Index += 2
                    Array.Copy(B_Id, 0, Buffer, Index, 2) : Index += 2
                    Array.Copy(B_Seq, 0, Buffer, Index, 2) : Index += 2
                    If (Data.Length() > 0) Then Array.Copy(Data, 0, Buffer, Index, Data.Length())
                    Return Buffer
                End Function
    #End Region
            End Structure
            Public Class CPing
    #Region "Contactes"
                Private Const DATA_SIZE As Integer = 32
                Private Const DEFAULT_TIMEOUT As Integer = 1000
                Private Const ICMP_ECHO As Integer = 8
                Private Const SOCKET_ERROR As Integer = -1
                Private Const PING_ERROR As Integer = -1
                Private Const RECV_SIZE As Integer = 128
    #End Region
    #Region "VARIABLES"
                Private _Open As Boolean = False
                Private _Initialized As Boolean
                Private _RecvBuffer() As Byte
                Private _Packet As Angel_Ping
                Private _HostName As String
                Private _Server As EndPoint
                Private _Local As EndPoint
                Private _Socket As Socket
    #End Region
    #Region "CONSTRUCTORS & FINALIZER"
                Public Sub New(ByVal hostName As String)
                    Me.HostName() = hostName
                    ReDim _RecvBuffer(RECV_SIZE - 1)
                End Sub
                Public Sub New()
                    Me.HostName() = Dns.GetHostName()
                    ReDim _RecvBuffer(RECV_SIZE - 1)
                End Sub
                Private Overloads Sub finalize()
                    Me.Close()
                    Erase _RecvBuffer
                End Sub
    #End Region
    #Region "Metodos"
                Public Property HostName() As String
                    Get
                        Return _HostName
                    End Get
                    Set(ByVal Value As String)
                        _HostName = Value
                        If (_Open) Then
                            Me.Close()
                            Me.Open()
                        End If
                    End Set
                End Property
                Public ReadOnly Property IsOpen() As Boolean
                    Get
                        Return _Open
                    End Get
                End Property
                Public Function Open() As Boolean
                    Dim Payload() As Byte
                    If (Not _Open) Then
                        Try
                            ReDim Payload(DATA_SIZE)
                            _Packet.Initialize(ICMP_ECHO, 0, Payload)
                            _Socket = New Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)
                            '   Estas dos lineas VS2008 indica que están obsoletas. se han reemplazado  por las dos siguientes
                            '_Server = New IPEndPoint(Dns.GetHostByName(_HostName).AddressList(0), 0)
                            '_local = New IPEndPoint(Dns.GetHostByName(Dns.GetHostName()).AddressList(0), 0)
                            _Server = New IPEndPoint(Dns.GetHostEntry(_HostName).AddressList(0), 0)
                            _Local = New IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList(0), 0)
                            _Open = True
                        Catch
                            Return False
                        End Try
                    End If
                    Return True
                End Function
                Public Function Close() As Boolean
                    If (_Open) Then
                        _Socket.Close()
                        _Socket = Nothing
                        _Server = Nothing
                        _Local = Nothing
                        _Open = False
                    End If
                    Return True
                End Function
                Public Overloads Function Ping() As Integer
                    Return Ping(DEFAULT_TIMEOUT)
                End Function
                Public Overloads Function Ping(ByVal timeOutMilliSeconds As Integer) As Integer
                    Dim TimeOut As Integer = timeOutMilliSeconds + Environment.TickCount()
                    Try
                        If (SOCKET_ERROR = _Socket.SendTo(_Packet.Serialize(), _Packet.Size(), 0, _Server)) Then
                            Return PING_ERROR
                        End If
                    Catch
                    End Try
                    Do
                        If (_Socket.Poll(1000, SelectMode.SelectRead)) Then
                            _Socket.ReceiveFrom(_RecvBuffer, RECV_SIZE, 0, _Local)
                            Return (timeOutMilliSeconds - (TimeOut - Environment.TickCount()))
                        ElseIf (Environment.TickCount() >= TimeOut) Then
                            Return PING_ERROR
                        End If
                    Loop While (True)
                End Function
    #End Region
            End Class
            Module MCheckSum
    #Region "Metodos"
                <StructLayout(LayoutKind.Explicit)> Structure UNION_INT16
                    <FieldOffset(0)> Dim lsb As Byte
                    <FieldOffset(1)> Dim msb As Byte
                    <FieldOffset(0)> Dim w16 As Short
                End Structure
                <StructLayout(LayoutKind.Explicit)> Structure UNION_INT32
                    <FieldOffset(0)> Dim lsw As UNION_INT16
                    <FieldOffset(2)> Dim msw As UNION_INT16     '
                    <FieldOffset(0)> Dim w32 As Integer
                End Structure
                Public Function Calculate(ByRef buffer() As UInt16, ByVal size As Int32) As UInt16
                    Dim Counter As Int32 = 0
                    Dim Cksum32 As UNION_INT32
                    Do While (size > 0)
                        Cksum32.w32 += Convert.ToInt32(buffer(Counter))
                        Counter += 1
                        size -= 1
                    Loop
                    Cksum32.w32 = Cksum32.msw.w16 + Cksum32.lsw.w16 + Cksum32.msw.w16
                    Return Convert.ToUInt16(Cksum32.lsw.w16 Xor &HFFFF)
                End Function
    #End Region
            End Module
        End Namespace

    End Namespace

     

    Saludos.

    miércoles, 6 de octubre de 2010 6:54