繁体   English   中英

当应用程序加载而不从 Application_Start() 调用它时,如何在 ASP.net MVC 中只运行一次方法

[英]How to run a method in ASP.net MVC only once when application Load Without calling it from Application_Start()

我有一个 ASP.Net MVC Web 应用程序,在这个应用程序中我有 IP 检测工作,IP 检测方法需要大约 30 秒才能获取 IP,这很好。 但是我只有 30 秒的时间来运行索引页面以及 IP 检测。 意味着如果我调用 IP 检测,那么将没有时间加载索引。 我正在从 Application_Start() 调用 IP 检测方法。 但是当它运行主页面时没有时间加载。 我想在自动加载应用程序后调用 IP 检测方法。怎么可能请帮助。

我有 IP 检测方法:

public void GetCityByIP()
        {
            abcEntities db = new abcEntities();
            string IPDetect = string.Empty;
            string APIKeyDetect = "Set API key";
            string city = "";
            string cityName = string.Empty;

            if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
            {
                IPDetect = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
            }
            else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
            {
                IPDetect = "192.206.151.131";
            }
            string urlDetect = string.Format("http://api.ipinfodb.com/v3/ip-city/?key={0}&ip={1}&format=json", APIKeyDetect, IPDetect);
            try
            {
                using (WebClient client = new WebClient())
                {
                    string json = client.DownloadString(urlDetect);
                    Location location = new JavaScriptSerializer().Deserialize<Location>(json);
                    List<Location> locations = new List<Location>();
                    locations.Add(location);
                    city = location.CityName;
                }
            }
            catch (WebException e)
            {
                city = "Toronto";
            }
            var getCityID = db.Macities.Where(c => c.CityName.Contains(city)).ToList();

            if ((getCityID != null) && (getCityID.Count > 0))
            {
                cityName = getCityID.FirstOrDefault().CityName;
            }
            else
            {
                getCityID = db.Macities.Where(c => c.CityName.Contains("Toronto")).ToList();
                cityName = getCityID.FirstOrDefault().CityName;
            }
            HttpContext.Current.Response.Cookies["CityName"].Value = cityName;
        }

我想设置 cookie 并将其用作整个应用程序中检测到的 IP 城市。我从 Start 方法调用它为:

 protected void Application_Start()
    {

        GetCityByIP();
    }

IP 检测方法也在全局文件中。 我在数据库中的城市有限,所以这就是为什么我使用数据库并在数据库城市中匹配城市(如果存在)然后 IP 方法设置在 cookie 中检测到的城市,否则将在 cookie 中设置默认城市。 提前致谢。

我不确定我是否真的了解您尝试执行的顺序,但是可以看看Owin和Startup。

http://www.asp.net/aspnet/overview/owin-and-katana/owin-startup-class-detection

配置:

<appSettings>  
  <add key="owin:appStartup" value="StartupDemo.Startup" />
</appSettings>

码:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using System.IO;

[assembly: OwinStartup(typeof(StartupDemo.Startup))]

namespace StartupDemo
{
   public class Startup
   {
      public void Configuration(IAppBuilder app)
      {
         app.Use((context, next) =>
         {
            TextWriter output = context.Get<TextWriter>("host.TraceOutput");
            return next().ContinueWith(result =>
            {
               output.WriteLine("Scheme {0} : Method {1} : Path {2} : MS {3}",
               context.Request.Scheme, context.Request.Method, context.Request.Path, getTime());
            });
         });

         app.Run(async context =>
         {
            await context.Response.WriteAsync(getTime() + " My First OWIN App");
         });
      }

      string getTime()
      {
         return DateTime.Now.Millisecond.ToString();
      }
   }
}

或者,您可以使用Task.Run使其异步运行。

    return TaskEx.Run(() =>
    {

            try
            {
                // Do some time-consuming task.
            }
            catch (Exception ex)
            {
                // Log error.
            }

    });

在问题更新后进行编辑:

由于它仅应为每个访问者运行一次,因此将其放入会话启动比应用程序启动更为合理。 请勿按照上述建议使用Owin,因为它仅在应用启动时运行。

Asp.Net MVC OnSessionStart事件

void Session_Start(object sender, EventArgs e) {
  // your code here, it will be executed upon session start
}

它必须是同步的吗?

为什么不从App_Start异步调用IP检测方法,然后继续加载索引页。

如果由于某种原因无法使用异步,请使用后台线程!

如果您使用的是Azure(不确定AWS是否具有类似功能),则可以使用启动任务。

https://msdn.microsoft.com/zh-CN/library/azure/hh180155.aspx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM