2017-12-04 9 views
0

작업을 사용하여 백그라운드에서 전자 메일을 보내고 있습니다. PDF (첨부 파일로 메일에 포함)가 생성 되었음에도 불구하고 (GeneratePdf()). 나는 예외 다음 얻을 : enter image description hereEF from Task : System.InvalidOperationException : 리더가 닫혔습니다.

편집 아래는 dbContext가로드 코드 (Startup.cs, 방법 ConfigureServices)입니다 : 아래

enter image description here

GetRegistrationOfChild를 호출하는 코드입니다. 그 후 생성자에서 DI로 해결됩니다.

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

+0

'dbContext'는 어디에서 왔습니까? – ViRuSTriNiTy

+0

코드가 어디에서 왔는지를 실제로 알려주지는 않았습니다. 가운데에 빠진 비트가 여기에 있습니다. 데이터를 검색 할 기회를 갖기 전에 컨텍스트를 닫거나/폐기하고 있습니까? – DavidG

+0

설명을 수정했습니다. dbContext는 생성자의 DI에 의해 처리됩니다. 나는 문맥을 닫거나 처리하지 않을 것이다. – user2810895

답변

2

많은 문제가 실제로 여기에있다. 귀하의 핵심 문제는 SendRegisterConfirmationAsync 방법에있을 가능성이 큽니다. 그러나 해당 메소드에 대한 코드를 제공하지 않았습니다. 짐작할 수 있겠지만 오류 메시지를 기반으로 스레드로부터 안전한 방식으로 using 문을 사용하고 있습니다.

그러나 이것은 비동기를 부적절하게 처리했기 때문에 가능할 수도 있습니다. 당신은 동기화 메서드에서 비동기 메서드를 호출하고 있습니다. SendEmail이 void를 반환하기 때문에 async 메서드의 반환 값을 삼키거나 비동기 메서드가 async void입니다.이 값은 이 아니며입니다. 두 경우 모두 비동기 메서드의 결과를 기다리지 않으므로 나머지 코드는 잠재적으로 종속성을 가지게됩니다. 예를 들어 DbContext과 같은 항목은 요청 범위이므로 비동기 메소드가 DbContext을 사용하지만 응답이 완료되기 전에 완료되지 않으면 문맥이 예외를 발생시켜 바로 아래에서 처리됩니다. 비동기를 사용하는 경우 이 필요합니다.

웹 응용 프로그램 컨텍스트에서 실제 "백그라운드"작업과 같은 것은 없습니다. Task.Run은 요청이 처리되는 동일한 풀에서 다른 스레드를 가져옵니다. 하나의 스레드가 돌아 오도록 허용 할 수 있지만 여전히 다른 스레드에 앉아 있기 때문에 가장 좋은 시나리오는 스스로 구입하지 않은 것입니다. 최악의 시나리오는 이제 서버의 처리량을 효과적으로 절반으로 줄이고 확장 능력을 손상시킨 것입니다.

백그라운드에서 수행하려는 경우 배경 으로, 즉 웹 응용 프로그램의 컨텍스트 외부로 오프로드하십시오. Hangfire 또는 Revalee과 같은 것을 사용할 수 있습니다.