2010-03-03 3 views
5

런타임시 servicehost의 App.Config에있는 connectionstring에서 데이터베이스 이름을 변경하고 나중에 다른 데이터베이스에 연결하여 데이터베이스 이름을 다시 시작하려고합니다. 이것은 정상적으로 작동하지만 애플리케이션이 여러 초 동안 종료 된 경우에만 작동합니다. 몇 초 동안 응용 프로그램을 종료하면 ConfigurationManager의 캐시가 지워집니다. 연결 스트링. 문제는이 종료 시간으로 인해 응용 프로그램에서 Application.Restart()를 사용할 수 없다는 것입니다.connectionstrings의 configurationmanager 캐시를 지우는 방법

이 캐싱 동작에 대한 이상한 점은 메모리에서 값이 업데이트 된 경우에도 (두 번째 요청시) 업데이트 된 값이 올바르게 표시된다는 것입니다. 그러나 응용 프로그램이 다시 시작되면 이전 값이 다시 나타납니다.

동작을 확인하려면 새 콘솔 앱을 만드십시오.

 ConfigurationManager.RefreshSection("connectionStrings"); 
     DbConnectionStringBuilder builder = new DbConnectionStringBuilder(); 
     Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     builder.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString; 

     //print initial value 
     Console.WriteLine("initial " + (string)builder["Initial Catalog"]); 

     //change value 
     builder["Initial Catalog"] = "ChangedDatabaseName"; 
     appConfig.ConnectionStrings.ConnectionStrings.Remove("DomainDBConnectionString"); 
     appConfig.ConnectionStrings.ConnectionStrings.Add(new ConnectionStringSettings("DomainDBConnectionString", builder.ConnectionString)); 
     appConfig.ConnectionStrings.SectionInformation.ForceSave = true; 
     appConfig.Save(ConfigurationSaveMode.Full); 
     ConfigurationManager.RefreshSection("connectionStrings"); 

     Console.ReadLine(); 

     DbConnectionStringBuilder builder2 = new DbConnectionStringBuilder(); 
     Configuration appConfig2 = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     builder2.ConnectionString = appConfig.ConnectionStrings.ConnectionStrings["DomainDBConnectionString"].ConnectionString; 
     Console.WriteLine("changed " + (string)builder2["Initial Catalog"]); 

     Console.ReadLine(); 

이 동작을 재현하려면 다음 Main 메서드에 다음 코드를 추가의 app.config가

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <connectionStrings> 
    <add name="DomainDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=InitialDBName;Integrated Security=SSPI;" /> 
    </connectionStrings> 
</configuration> 

파일 추가, 당신은 (F5 타격에 의해) 응용 프로그램을 실행하는 데 필요 닫아. 나중에 solutionname.exe.config 파일에 수정 된 값이 표시됩니다. 응용 프로그램을 다시 실행하면 (, solutionname.exe 번을 두 번 클릭하여 실행) 응용 프로그램을 종료 한 직후 또는 몇 초 기다렸다가 즉시이 동작을 수행하면 동작이 달라집니다.

내 생각에 configsection은 ConfigurationManager.RefreshSection ("connectionStrings") 때문에 다시 읽어야합니다. 하지만 apparenatelly 이것은 광고 된대로 작동하지 않습니다.

+0

내 태그를 편집 한 사람에게. 이것은 ASP.Net과 아무 관련이 없습니다. 내 servicehost는 콘솔 응용 프로그램입니다. –

+1

충분히 공정하지만 여전히 그렇습니다.net - 질문에 태그를 달지 않을 위험은 다른 사람들이 당신을 위해 태그를 붙이면 잘못 받아 들일 것입니다. :) – skaffman

답변

0

문제는 처음에는 Visual Studio (디버거 사용)에서 응용 프로그램을 실행한다는 사실에있는 것 같습니다.

bin/debug 디렉토리에서 응용 프로그램을 실행하면 캐싱 문제가없는 것 같습니다.

내 프로덕션 환경에서는 내 문제가 해결됩니다 (즉, 문제가 해결됨). 그러나 이것은 행동의 차이에 대한 나의 호기심을 죽이지는 않습니다.

9

2 것 :

먼저 당신이 solutionname.exe.config를 사용하지 않는 디버그 모드에있을 때; 실제로 solutionname.vshost.exe.config을 사용하고 있으므로 응용 프로그램을 중지하자마자 solutionname.vshost.exe.config 파일이 원래 버전으로 돌아 가기 때문에 일치하지 않는 동작이 발생합니다. 변경 사항을 잃어 버렸습니다.

초이 코드 줄 ConfigurationManager.RefreshSection("connectionStrings"); 은 항상 예상대로 작동하지 않습니다. 부모님 섹션이나 섹션 그룹을 새로 고치는 것이 더 좋은 것으로 나타났습니다. 이 경우 "구성"이됩니다.

시도해주세요. ConfigurationManager.RefreshSection("configuration");

+0

ConfigurationManage.RefreshSection ("configuration")이 나에게 도움이되지 않았습니다. (PS)에 대한 변경 사항 저장 후 Application.Restart() 사용 Program.Main()에서 Application.Restart()를 호출해야합니다. 그렇지 않으면 재시작 응용 프로그램이 2 개의 인스턴스에서 시작될 것입니다. – Prokurors

+0

나는 유감스럽게도 "구성"에서 RefreshSection을 실행하십시오. – SondreB

관련 문제