Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151

    Riferimento a un oggetto...

    Salve,
    so che è un argomento già trattato diverse volte, ma leggendo gli altri thread non sono risucito a venirne a capo.
    In questa classe presa da Aspitalia per effettuare le operazioni pianificate tramite asp.net ho messo una classe creata da me:
    codice:
    using System;
    using System.Timers;
    using System.Web;
    using MyStats;
    
    public class MyGlobal:HttpApplication
    {
    
        private Timer OpTimer;
    	//orario stabilito della prima operazione
    	//e per le successive (calcolato automaticamente)
        public static DateTime When;
    	
    	//riesegui ogni n ore
        public static byte Every;
    	
    
    public MyGlobal():base()
    {
    	//orario stabilito della prima operazione
    	//non indicare la data in previsione di futuri riavvi di iis
    	When=DateTime.Parse("22:53");
    	//riesegui ogni n ore
    	Every=24;
    	StartTimer();
    }
    
    public void OnTimedEvent(object source, ElapsedEventArgs e) 
    {
    
    	//Richiamo classe da me creata
    	try
    	{
    	Stats hit=new Stats();
    	hit.Analyze();
    	Application["debug"]="ok";
    	}
    	catch (System.Exception ex){
    	
    	Application["debug"]=ex;
    	}
    	//riimposto il timer per portarlo avanti di n ore
    	When=When.AddHours(Every);
    
    	//riprendo l'intervallo cos prendo in considerazione il tempo di elaborazione passato
    	//con il tempo potrebbe sballare
    	OpTimer.Interval=GetInterval();
    	OpTimer.Start();
    
    }
    
    private double GetInterval()
    {
    
    	TimeSpan diff=When.Subtract(DateTime.Now);
    	
        //risultato in millisecondi
    	return diff.Ticks / 10000;
    }
    
    private void StartTimer()
    {
    //se l'ora in cui deve partire è più piccola di oggi (visto che la parserizza con la data odierna)
    //lo portiamo alla prossima esecuzione
    if (When<DateTime.Now) {
        //aumento la data dell'operazione dell'intervallo dato
        //fino a quando è maggiorne dell'ora odierna
        while (When<=DateTime.Now){
            When=When.AddHours(Every);
        }
    }
    
    	OpTimer=new Timer(GetInterval());
    
    	OpTimer.AutoReset=false;
    	OpTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
    	OpTimer.Enabled=true;
    	
    }
    
    
    }
    Però se controllo la variabile Application["debug"] dopo l'esecuzione pianificata ottengo l'errore

    System.NullReferenceException: Riferimento a un oggetto non impostato su un'istanza di oggetto. at MyStats.Stats.Analyze() at MyGlobal.OnTimedEvent(Object source, ElapsedEventArgs e)

    Io lavoro prevalentemente in vb.net e non utilizzo VS.net.
    Mi sapete dire come devo istanziare la chiamata alla classe da me creata?
    Grazie

  2. #2
    Quel codice è stato scritto con Visual Studio, e si basa sulla classe del global.asax. La puoi riscrivere senza tanti problemi anche come normale codice nel global.asax (io avevo utilizzato lo stesso oggetto Timer molto tempo fa senza problemi). Il problema è riadattare il codice in modo corretto. Potresti provare a scrivere:
    codice:
    <%@ Application language="c#" Classname="MainApp" %>
    <%@ Import Namespace="System" %>
    <%@ Import Namespace="System.Timers" %>
    <%@ Import Namespace="System.Web" %>
    <%@ Import Namespace="MyStats" %>
    
    <script runat=server>
    private Timer OpTimer;
    public static DateTime When;
    public static byte Every;
    void Application_OnStart(Object s,EventArgs s)
    {
    When=DateTime.Parse("22:53");
    Every=24;
    StartTimer();
    }
    public void OnTimedEvent(object source, ElapsedEventArgs e) 
    {
    
    	//Richiamo classe da me creata
    	try
    	{
    	Stats hit=new Stats();
    	hit.Analyze();
    	Application["debug"]="ok";
    	}
    	catch (System.Exception ex){
    	
    	Application["debug"]=ex;
    	}
    	//riimposto il timer per portarlo avanti di n ore
    	When=When.AddHours(Every);
    
    	//riprendo l'intervallo cos prendo in considerazione il tempo di elaborazione passato
    	//con il tempo potrebbe sballare
    	OpTimer.Interval=GetInterval();
    	OpTimer.Start();
    
    }
    
    private double GetInterval()
    {
    
    	TimeSpan diff=When.Subtract(DateTime.Now);
    	
        //risultato in millisecondi
    	return diff.Ticks / 10000;
    }
    
    private void StartTimer()
    {
    //se l'ora in cui deve partire è più piccola di oggi (visto che la parserizza con la data odierna)
    //lo portiamo alla prossima esecuzione
    if (When<DateTime.Now) {
        //aumento la data dell'operazione dell'intervallo dato
        //fino a quando è maggiorne dell'ora odierna
        while (When<=DateTime.Now){
            When=When.AddHours(Every);
        }
    }
    
    	OpTimer=new Timer(GetInterval());
    
    	OpTimer.AutoReset=false;
    	OpTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
    	OpTimer.Enabled=true;
    	
    }
    </script>
    Non testato. Non conosco il namespace "MyStats".

    Ciao
    AZ [Microsoft - .NET MVP]
    Mia Home page: http://ciclismo.sitiasp.it
    Asp.Net community: http://www.aspitalia.com
    Il mio blog: http://blogs.aspitalia.com/az

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151
    Ora provo e ti faccio sapere

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151
    Anche così non funziona.
    Mi da errore nella riga hit.Analyze()
    il codice del metodo Analyze() è questo
    codice:
    Public Sub Analyze()
     Dim ASPSession as String
     Dim Agente as String
     Dim IPUtente as String
     Dim Duratavisita as Integer
     Dim Npagine as Integer
     Dim Data as Datetime
     Dim Country as Countrylookup.CountryLookup = New Countrylookup.Countrylookup(httpContext.Current.Server.Mappath("data/GeoIP.dat"))
     Dim Paese as String
     Dim myconn as New Oledbconnection(System.Configuration.ConfigurationSettings.AppSettings("MM_CONNECTION_STRING_stats"))
     Dim mycomm as new OledbCommand("Select Sessione, Agente, IPUtente From RawStats  Where Elaborato=0  and Tempo<Date() and IPUtente not in (Select IP from IPFilters) Group By Sessione, Agente, IPUtente", myconn)
     myconn.open()
     Dim myread as OLEDBDataReader=mycomm.executereader()
     While myread.read()
     ASPSession=myread.getvalue(0)
     Agente=myread.getvalue(1)
     IPUtente=myread.getvalue(2)
     Browser(Agente,ASPSession)
     DurataVisita=Durata(ASPSession)
     NPagine=CountPage(AspSession)
     Data=getDate(AspSession)
     Paese="N/A"
     'httpContext.Current.response.write(getHostname(IPUtente) & "
    ")
     'httpContext.Current.response.write(getReferrer(ASPSession) & "
    ")
     If (Not Instr(IPUtente,"192.168")>0) and (Not InStr(IPUtente,"10.")>0) then Paese= Country.LookupCountryName(IPUtente)
     Dim myconn2 as New Oledbconnection(System.Configuration.ConfigurationSettings.AppSettings("MM_CONNECTION_STRING_stats"))
     Dim inscomm as new OledbCommand("insert Into Visite (Aspsession,Data,durata,npagine,idbrowser,idos,Paese,IPAddress) VALUES (@ASPSes,@Data,@Durata,@NPagine,@IDBw,@IDOS,@Paese,@IPAddress)", myconn2)
     myconn2.open()
     inscomm.Parameters.Add("@ASPSes", OLEDBType.varchar,255)
     inscomm.Parameters("@ASPSes").value=ASpSession
     inscomm.Parameters.Add("@Data", OLEDBType.date)
     inscomm.Parameters("@Data").value=Data
     inscomm.Parameters.Add("@Durata", OLEDBType.integer)
     inscomm.Parameters("@Durata").value=DurataVisita
     inscomm.Parameters.Add("@NPagine", OLEDBType.integer)
     inscomm.Parameters("@NPagine").value=Npagine
     inscomm.Parameters.Add("@IDBw", OLEDBType.integer)
     inscomm.Parameters("@IDBw").value=BwID
     inscomm.Parameters.Add("@IDOS", OLEDBType.integer)
     inscomm.Parameters("@IDOS").value=OSID
     inscomm.Parameters.Add("@Paese", OLEDBType.varchar,255)
     inscomm.Parameters("@Paese").value=Paese
     inscomm.Parameters.Add("@IPAddress", OLEDBType.varchar,255)
     inscomm.Parameters("@IPAddress").value=IPUtente
     inscomm.executenonquery
     Dim upcomm as New OledbCommand("Update RawStats Set Elaborato=-1 Where Sessione=@ASPSes", myconn2)
     upcomm.Parameters.Add("@ASPSes", OLEDBType.varchar,255)
     upcomm.Parameters("@ASPSes").value=ASpSession
     upcomm.executenonquery()
     myconn2.close()
     end while
     myconn.close()
     end sub
    che funziona se richiamato da una pagina aspx

    P.S. ti era scappata un s di troppo in questa riga
    Application_OnStart(Object s,EventArgs s)

  5. #5
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151
    ho trovato dove sta il problema.
    E' la seguente riga

    Dim Country as Countrylookup.CountryLookup = New Countrylookup.Countrylookup(httpContext.Current.Se rver.Mappath("data/GeoIP.dat"))

    Evidentemente non posso usare httpContext in questo "contesto"
    C'è un modo equivalente per utilizzare Server.mappath da global.asax?


    Buon Natale a tutti.

  6. #6
    Nella funzione richiamata dal Timer non è possibile richiedere il percorso relativo dall'oggetto Httpontext visto che questo funzione non è stata invocata da una richieste http.

    In questi casi hai diversi trucchi per risolvere, io solitamente memorizzo il percorso in una variabile "static". Per esempio:
    codice:
    <script runat=server>
    private Timer OpTimer;
    public static DateTime When;
    public static byte Every;
    public static string Percorso;
    void Application_OnStart(Object s,EventArgs s)
    {
    When=DateTime.Parse("22:53");
    Every=24;
    Percorso=HttpContext.Current.Request.ApplicationPath
    StartTimer();
    }
    Quindi quella linea di codice la puoi correggere in questo modo:
    codice:
     Dim Country as Countrylookup.CountryLookup = New Countrylookup.Countrylookup(Percorso & "/data/GeoIP.dat")
    Ciao
    AZ [Microsoft - .NET MVP]
    Mia Home page: http://ciclismo.sitiasp.it
    Asp.Net community: http://www.aspitalia.com
    Il mio blog: http://blogs.aspitalia.com/az

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151
    Scusa la domanda banale, ma come dichiaro la variabile Percorso all'interno di Analyze affinchè prenda il valore assegnatole nel global.asax?

  8. #8
    Essedo shread è pubblicamente accessibile da qualsiasi pagina della tua webapplication. L'unico accorgimento (mia dimenticanza) è che devi referenziarti ad essa anche con il nome della classe del global.asax:
    codice:
    Dim Country as Countrylookup.CountryLookup = New Countrylookup.Countrylookup(MainApp.Percorso & "/data/GeoIP.dat")
    Ciao
    AZ [Microsoft - .NET MVP]
    Mia Home page: http://ciclismo.sitiasp.it
    Asp.Net community: http://www.aspitalia.com
    Il mio blog: http://blogs.aspitalia.com/az

  9. #9
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    151
    ora mi dice che non è dichiarata MainApp.

    Comunque ho risolto mettendo il percorso nel web.config tramite
    <add key="GeoIP_stats"

  10. #10
    MainApp è il nome della classe del global.asax così come te l'avevo scritto nel mio esempio.

    Ciao
    AZ [Microsoft - .NET MVP]
    Mia Home page: http://ciclismo.sitiasp.it
    Asp.Net community: http://www.aspitalia.com
    Il mio blog: http://blogs.aspitalia.com/az

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.