2012-07-11 6 views
1

데이터 메서드 내에서 저장 프로 시저 호출을 비동기 호출로 전환하려고합니다. 이것은 원래의 방법입니다 :Task.Factory.StartNew() 데이터 메서드 - 전달 this.Database?

public void InsertFoo(Foo foo) 
{ 
    Task.Factory.StartNew(() => 
    { 
     this.Database.SomeStoredProcedure(foo); 
    }); 
} 

그러나, 나는 this.Database가 null하는 런타임 오류가 발생합니다 :

public void InsertFoo(Foo foo) 
{ 
    this.Database.SomeStoredProcedure(foo); 
} 

내 첫 번째 시도가이 있었다. (. this.Database은 L2S 데이터 컨텍스트입니다)

그리고 제가 조사를 좀 해봤 내 자신의 로컬 복사본이 그것을 할 것입니다 만들 생각 :

그러나
public void InsertFoo(Foo foo) 
{ 
    MyDataContext db = this.Database; 

    Task.Factory.StartNew(() => 
    { 
     db.SomeStoredProcedure(foo); 
    }); 
} 

, DB가 배치가 실제로에서 사용되기 전에 다른 런타임 오류가 발생합니다.

이 스레드를 스레드 메서드에 전달하기 만하면됩니다. 그게 가능하니? 그렇다면 어떻게? this.Database 클래스 인스턴스가 사라 졌으므로 메서드가 반환 될 때 파괴 될 것입니다, 그래서 어떻게 해결할 수 있는지 잘 모르겠습니다.

+2

비동기 작업 자체 내에서 컨텍스트를 만들어야합니다. 왜냐하면 부모 스레드의 변수 상태가 파괴 될 수 있기 때문입니다. 컨텍스트 인스턴스는 매우 가볍기 때문에 개별 작업 항목을 수행 할 때마다 새 인스턴스를 만드는 작업 단위 패턴을 사용할 수 있습니다. – mellamokb

+0

비동기 작업 자체의 컨텍스트를 어떻게 만듭니 까? –

+0

'MyDataContext db = new MyDataContext()'? – mellamokb

답변

2

Bob. InsertFoo 메서드가 즉시 반환 될 때 포함하는 개체 인스턴스를 컬렉션에 사용할 수 있으므로 호출이 데이터베이스에 이루어지면 데이터베이스 인스턴스가 삭제됩니다.

using(var xx = new FooContainer()){ 

xx.Foo(foo); 

} 

fooContainer는 foo 메서드 내에서 비동기 호출이 실행되기 전에 처리합니다.

필자는 InsertFoo를 비동기 적으로 호출하는 것이 좋습니다. 대신 해당 메서드 내에서 비동기 호출을 수행하는 것이 좋습니다.

Task.Factory.StartNew(()=> xx.InsertFoo(foo)) 행에 뭔가가 있으며 완료시 계속을 사용하여 객체가 포함 된 xx을 정리할 수 있습니다.

+0

그럴 필요가 있습니다. 나는 호출 코드의 복잡성 때문에 그것을 피하기를 희망했다. –