6

나는 올바른 방향으로 생각하지 않을 것입니다. 필자는 Dependency Injection과 ASP.Net Core를 처음 접했습니다.종속성 주입을 통한 백그라운드 작업을위한 DbContext

필자는 ASP.Net 핵심 웹 사이트를 갖고 있으며,이 작업 중 하나는 Excel 시트에서 사용자가 업로드 할 데이터베이스로 데이터를 가져 오는 것입니다. 엑셀 시트는 거대 할 수 있고 데이터 변환 작업은 시간이 걸리기 때문에 백그라운드에서 수행해야합니다. 즉, 사용자가 시트를 업로드하면 응답이 즉시 전송되고 백그라운드 작업/스레드가 데이터를 가져옵니다.

Task.Run(() => ProcessImport(model)); 

의 I가로 실행 문제 프로세스 가져 오기 방법은 ASP.Net 의존성 삽입 컨테이너를 통해 AppDbContext 접근 저장소 클래스가 서비스를 호출하는 것입니다 :

나는으로 백그라운드 작업을 실행하려고 Scoped로 추가되고 응답이 반송되면 컨텍스트가 삭제됩니다. 처리가 끝난 후 컨텍스트를 사용할 수 없다는 런타임 예외가 발생합니다.

내 질문에이 상황을 처리하는 가장 좋은 방법은 무엇입니까? AppDbContext 싱글 톤을 만들어야합니까? ProcessImport 메서드에서 AppDbContext의 새 인스턴스를 만들고이를 전달해야합니까? DbContext는 스레드로부터 안전하지 않으므로 읽었습니다. 좋은 접근 방법입니까?

+0

을 아니요 : https://stackoverflow.com/questions/3266295/net-entity-framework-and-transactions/3266481#3266481 – Steven

+0

맞지만 다른 스레드에서 실행중인 작업을 다루는 방법은 DbContext에 액세스해야합니까? –

+3

어쨌든 이것은 위험한 패턴입니다. ASP.Net 응용 프로그램을 사용하여 [장기 실행 화재 및 잊어 버리는 작업] (http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx)을 사용해서는 안됩니다. 당신이 올바르게한다면, 그 일은 그 자체의 과정에서 실행되고 전체 DI 이슈는 사라집니다. –

답변

10

IServiceScopeFactory 인스턴스 (싱글 톤)를 작업에 전달해야합니다.

작업 내에서 데이터가 도착하면 CreateScope()을 새로 만들고 해당 범위에서 서비스를 요청해야합니다. 데이터 처리가 완료되면이 범위를 삭제합니다 (단, 다음 실행에는 IServiceScopeFactory 참조).

예를 들어 this을 참조하십시오. 이 라이브러리로 작고 빠른 작업을 수행합니다.

거트/장기 실행 작업의 경우 Gert가 쓴 것처럼 작업이 항상 완료 될 때까지만 의존하지 마십시오. 다시 시작할 준비가되어 같은 데이터를 다시 처리 할 준비를하십시오. 고장

+0

내 시나리오에 적용하는 방법을 완전히 이해하지 못했습니다. 컨트롤러에서 호출되는 ImportService라는 클래스가 있는데, 현재 데이터베이스에 액세스하기 위해 저장소 클래스를 주입하고 있습니다. 내 ProcessImport 메서드에서 이러한 저장소 클래스를 사용하고 싶습니다. 정확하게 이해한다면, (var scope = ServiceScopeFactory.CreateScope()) 을 사용하여 메소드의 본문을 묶는다면, 블럭의 수명 동안 주입 된 클래스를 마지막으로 만들 것인가? 이 클래스의 새로운 인스턴스? –

+0

아니요, 새로운 범위는 db (및 다른 범위 수명) 클래스의 새로운 인스턴스를 제공합니다. 사용자가 ProcessImport가 완료 될 때까지 기다리기를 원하지 않는다면 scope-lifetime 인스턴스를 공유해서는 안됩니다. 요청 범위는 모든 요청을 처리 할 수있는 요청이 끝나면 삭제됩니다. – Dmitry

3

질문 :

  1. 이 상황을 처리하는 가장 좋은 방법은 무엇입니까?

    API가 장기 실행 작업을 처리하는 것은 이상적이지 않습니다. 프로세스를 백그라운드 응용 프로그램에 위임 할 수 있습니다.

  2. AppDbContext 싱글 톤을 만들어야합니까?

    트랜잭션 관리와 같은 문제가 발생할 수 있으므로 웹 응용 프로그램 시나리오에서는 dbContext가 싱글 톤이어서는 안됩니다.

  3. 이 상황을 처리하는 가장 좋은 방법은 무엇입니까?

    고장 다양한 서비스/과정 :

    • 파일을 것이다 API. 이상적으로 API는 파일을 입력으로 가져와 디스크 나 데이터베이스에 유지해야합니다.
    • 파일을 처리 할 서비스입니다. 이 구성 요소/서비스를 별도의 라이브러리로 만듭니다. 그런 다음 콘솔 앱에서이 라이브러리를 사용합니다. 이렇게하면 성능을 프로파일 링 할 수 있습니다. 그것을 비동기 적 방법으로 만들어 화재와 잊어 버리게하십시오.이렇게하면 코드를 재사용 할 수있는 유연성이 생깁니다.
    • 파일 업로드가 많지 않은 경우 API 컨트롤러에서 라이브러리를 다시 사용하고 QueueBackgroundWorkItem을 사용하여 메서드를 실행할 수 있습니다. http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
  4. 내가 ProcessImport 방법에 AppDbContext의 새 인스턴스를 만들 경우, 그것을 따라 통과 : 참조 여기를 참조하십시오?

    스레드로부터 안전하지 않으므로 각 스레드에서 dbContext 클래스의 별도 인스턴스를 만들고 사용하십시오.

  5. DbContext는 스레드로부터 안전하지 않으므로 읽기 때문에 좋은 접근 방법입니까? EF dbContext를 사용하는 심도있는 가이드

    ,이 블로그를 체크 아웃 : "나는 AppDbContext 싱글을해야"http://mehdi.me/ambient-dbcontext-in-ef6/

관련 문제