다음 코드는 SQL Server에서 가져온 고급 데이터 구조를 작성하는 데 필요한 데이터가 완료되면 UI를 업데이트합니다. 사용 된 코드는홀수 작업 병렬 라이브러리 InvalidOperationException
private void BuildSelectedTreeViewSectionAsync(TreeNode selectedNode)
{
// Initialise.
SqlServer instance = null;
SqlServer.Database database = null;
// Build and expand the TreeNode.
Task task = null;
task = Task.Factory.StartNew(() => {
string[] tmpStrArr = selectedNode.Text.Split(' ');
string strDatabaseName = tmpStrArr[0];
instance = SqlServer.Instance(this.conn);
database = instance.GetDatabaseFromName(strDatabaseName);
}).ContinueWith(cont => {
instance.BuildTreeViewForSelectedDatabase(this.customTreeViewSql,
selectedNode, database);
selectedNode.Expand();
task.Dispose();
}, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
this.MainUiScheduler);
}
입니다. 이것은 내 주요 개발 기계에서와 같이 작동합니다. 즉, database
개체의 빌드를 완료 한 다음 UI에서 UI를 업데이트하고 task
(작업 개체)을 삭제합니다.
그러나, 나는 다른 컴퓨터에 대한 몇 가지 테스트를하고있다 그리고 내가 InvalidOperationException
를 얻을,이 때문에 작업이 완료 될 때까지 실행하지 않는 한 계속 cont
가 발생해서는 안 여전히 Running
상태에서, 그러나 task
에 task.Dispose()
이다 .
다음은 예외가 발생하면 코드가 디버거에서 어떻게 표시되는지를 보여줍니다 :
I am aware that it almost always unneccessary to call Dispose
on tasks. ?이 질문은 당신이 위의 일을하려고하는 확신 **
나는이 사실을 믿지 않는다. 첫 번째 스 니펫에서 수행하는 방식으로 작업 및 연속을 정의 할 수 없습니다. 연속에서'task'를 참조하기 위해서는'Task'의 인스턴스를 생성 한 다음 그것에 할당해야합니다. ContinueWith (cont => {task.Dispose();});'task'가 범위 내에 있지 않으므로 _never_ 작업 할 것입니다 (var task = TaskFactory.StartNew ... (() => {...}). '. 'var task = null;''task = TaskFactory.StartNew ... (() => {...}) ContinueWith (cont => {task.Dispose();}); 'Task' 객체'task'에 행위를 버리십시오, 내가 여기에 정신을 보지 않으면 ... -] – MoonKnight
Ps. 시간 내 주셔서 감사합니다 ... – MoonKnight
@Killercam 코드를 업데이트했습니다. 첫 번째 코드 단편은 코드의 복제였으며 맞습니다. 변수가 먼저 선언 되어야만 클로저에서 액세스 할 수있었습니다. * 중요한 부분은 아니지만 *. – casperOne