2012-01-20 1 views
1

일부 JSON을 반환하는 컨트롤러 메서드가 있습니다. 콜렉션에서 콜렉션을 꺼내서 콜렉션에서 첫번째 아이템을 가져 와서 콜렉션에서 제거합니다. 메서드의 시작 부분에서 카운트가 1이면 0이됩니다.ASP.NET 세션이 업데이트시 스레드간에 동기화되지 않습니까?

같은 수식을 사용하여 콜렉션을 다시 검색하면 콜렉션 수가 더 적음을 확인할 수 있습니다.

지금까지 간단한 것들.

후속 요청에서 컬렉션은 세션에서 다시 가져 오지만 예상 개수에 0이 아닌 1이 있습니다. 이전에 제거 된 항목은 제거되지 않았습니다! 왜 이런거야?

충분한 요청이 이루어 지더라도 카운트는 실제로 0으로 끝납니다. 세션 개체가 모든 스레드에서 동기화되는 데 30 초 정도 걸리는 것처럼 보입니다.

정말 그렇게 할 수 있습니까? MVC4 (이전 버전도 될 수 있습니까?)에 이상한 세션 동기화 문제가 있습니까?

기본 InProc 세션 공급자 및 설정을 사용하고 있습니다.

여기 로그입니다 :

Thread Level Logger Message 
23 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

16 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
16 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
16 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

23 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
23 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

24 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
24 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
24 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

9 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
9 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
9 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

14 DEBUG ProjectMvc.Controllers.RpcController Pre-processing - Tasks.Count: 1 
14 DEBUG ProjectMvc.Controllers.RpcController Post processing - SessionID: asaq1v5afu0pwz13at4a24hl 
14 DEBUG ProjectMvc.Controllers.RpcController Post processing - Tasks.Count: 0 

세션에서 수집 내가 그것을 해결하려면 데이터베이스에이 물건을 저장해야 다른 요청에 대해 업데이트되지 않는 이유는 운동을 할 수 없습니다.

<sessionState mode="InProc" customProvider="DefaultSessionProvider"> 
     <providers> 
      <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> 
     </providers> 
    </sessionState> 

편집 2

I : 여기에 내가 세션의 Web.config에있는 무엇

public ActionResult GetCoordinatesTask() 
    { 
     var user = Session["User"] as IUser; 
     if (user == null) 
     { 
      Logger.LogError(this, "No user in session!"); 
      return Json(null, JsonRequestBehavior.AllowGet); 
     } 

     if (user.PhotoGeocodingTasks == null || user.PhotoGeocodingTasks.Count == 0) 
      return Json(null, JsonRequestBehavior.AllowGet); 

     lock (user.PhotoGeocodingTasks) 
     { 
      Logger.LogDebug(this, "Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count); 

      var task = user.PhotoGeocodingTasks[0]; 
      if (!user.PhotoGeocodingTasks.Remove(task)) 
       Logger.LogError(this, "Could not remove geocoding task after picking it up!"); 

      var encodedTask = new Dictionary<string, string> 
      { 
       {"photoid", task.PhotoId.ToString(CultureInfo.InvariantCulture)}, 
       {"latlong", task.Latitude + "," + task.Longitide} 
      }; 

      Logger.LogDebug(this, "Post processing - SessionID: " + Session.SessionID); 
      Logger.LogDebug(this, "Post processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count); 

      return Json(encodedTask, JsonRequestBehavior.AllowGet); 
     } 
    } 

편집

: 여기

코드입니다 또한 이 작업 데이터를 HttpRuntime.Cache에 저장하려고 시도했지만 (사용자 ID를 기준으로) 동일한 결과를 얻었습니다. 다른 요청에 대한 업데이트 된 값이 없습니다. 그것은 내 구성에서 동기화가 비활성화 된 것과 같습니다.

두 컴퓨터에서이 코드를 사용해도 동일한 결과가 나타납니다.

+1

세션은 MVC와 관련이 없습니다. – SLaks

+0

코드를 알려주십시오. – SLaks

+0

물론, 나는 내 게시물을 편집했습니다. – Amethi

답변

1

여기서는이 동작을 보지 못합니다. 내 표본을 시험해 볼 수 있니?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using NLog; 
using System.Globalization; 
using System.Threading; 

namespace Mvc4Application.Controllers 
{ 
    public class GeoCodingTask 
    { 
     public string Photoid{get;set;} 
    } 

    public class User 
    { 
     public List<GeoCodingTask> PhotoGeocodingTasks {get;set;} 
    } 

    public class HomeController : Controller 
    { 
     private static Logger _logger = LogManager.GetCurrentClassLogger(); 

     public ActionResult SetupCoordinatesTask() 
     { 
       User user = new User{ PhotoGeocodingTasks = new List<GeoCodingTask>()}; 
       user.PhotoGeocodingTasks.Add(new GeoCodingTask{ Photoid= "id1"}); 
       user.PhotoGeocodingTasks.Add(new GeoCodingTask { Photoid = "id2" }); 
       Session["User"] = user ; 

      return View("GetCoordinatesTask"); 
     } 

     public ActionResult GetCoordinatesTask() 
     { 
      User user = (User)Session["User"]; 
      if (user == null) 
      { 
       _logger.Error("No user in session!"); 
       return View(); 
      } 
      if (user.PhotoGeocodingTasks == null) 
       _logger.Debug("PhotoGeocodingTasks - null "); 
      if (user.PhotoGeocodingTasks.Count == 0) 
      { 
       _logger.Debug("Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count); 
       return View(); 
      } 
      lock (user.PhotoGeocodingTasks) 
      { 
       _logger.Debug("Pre-processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count); 
       var task = user.PhotoGeocodingTasks[0]; 
       if (!user.PhotoGeocodingTasks.Remove(task)) 
        _logger.Error("Could not remove geocoding task after picking it up!"); 

       _logger.Debug("Post processing - SessionID: " + Session.SessionID); 
       _logger.Debug("Post processing - PhotoGeocodingTasks.Count" + user.PhotoGeocodingTasks.Count); 
       return View(); 
      } 
     } 

    } 
} 

내가 처음 2 번 http://localhost:1631/home/GetCoordinatesTask에 다음 설정으로 세션을 http://localhost:1631/home/SetupCoordinatesTask를 호출

결과는

thread:19|2012-01-20 22:12:51.0492|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count2 
thread:19|2012-01-20 22:12:51.0652|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - SessionID: e4tawytx2mfq2msc3y2ajzl3 
thread:19|2012-01-20 22:12:51.0652|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - PhotoGeocodingTasks.Count1 
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count1 
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - SessionID: e4tawytx2mfq2msc3y2ajzl3 
thread:10|2012-01-20 22:13:01.0928|DEBUG|Mvc4Application.Controllers.HomeController|Post processing - PhotoGeocodingTasks.Count0 
thread:15|2012-01-20 22:13:02.6698|DEBUG|Mvc4Application.Controllers.HomeController|Pre-processing - PhotoGeocodingTasks.Count0 

당신이 tyour 코드를 단순화하고 전체 샘플을 게시 할 수있다?

+0

와우, Malcom에게 시간을내어 주셔서 감사합니다. 예상 한대로 샘플을 복제하고 작업을 추가 한 다음 세션에서 해당 세션을 제거하고 세션에서 제거합니다. 회신하기 전에 작업을 수행하기위한 새로운 코드를 작성했습니다. HttpRuntime 캐시에 저장되어 있고 크로스 스레드/요청 업데이트 (세션 캐시에 아무렇지로 저장된 내용을 읽은 후 의미가 있습니다)의 동일한 나쁜 영향을 받았습니다. 구성 문제와 같은 느낌이 있습니다. – Amethi

+0

두 애플 리케이션 사이의 web.configs 및 몇 가지 차이점을했지만 같은 시도 결과. – Amethi

1

개발자 오류. 당황 스럽지만, 마지막 버그를 처리 한 후에도 새 작업을 계속 작성한 버그가있었습니다.이 질문을 삭제하겠습니다.

모두 Malcom과 같은 시간을내어 주셔서 감사합니다.

+0

제이 - 개발자 오류 - 뻔뻔스럽지 않다. –

+0

나는 충격적인 행동을 알고있다. – Amethi

관련 문제