2016-06-01 4 views
1

저는 Xamarin으로 개발 된 모바일 응용 프로그램을 개발 중이며, 그때마다 응용 프로그램이 충돌하여 다음 예외가 발생합니다."시작된 작업이 완료되지 않았습니다."시작되지 않은 작업에 대한 예외가 발생했습니다.

System.InvalidOperationException 완료된 작업에서 Start가 호출되지 않을 수 있습니다. 명확하게하기 위해

이는 이런 기능의 더 많거나 적은 구조입니다 : 내가 버그를 재현하기 위해 관리 할 수 ​​없습니다

CancellationTokenSource tokenSource; 

    void Function(bool condition1, bool condition2) 
    { 
     if (tokenSource != null) 
     { 
      tokenSource.Cancel(); 
      tokenSource.Dispose(); 
      tokenSource = null; 
     } 

     Task completionTask = null; 

     if (condition1) 
     { 
      tokenSource = new CancellationTokenSource(); 
      completionTask = new Task(async() => 
       { 
        await Task.Delay(1000); 
        if (tokenSource != null && !tokenSource.IsCancellationRequested) 
        { 
         InvokeOnMainThread(Function2); 
        } 
       }, tokenSource.Token); 
     } 

     if (condition2) 
     { 
      TaskFactory.StartNew(() => 
       { 
        ... 
       }).ContinueWith(() => 
       { 
        if (completionTask != null) 
        { 
         completionTask.Start(); 
        } 
       }); 
     } 
     else 
     { 
      if (completionTask != null) 
      { 
       completionTask.Start(); 
      } 
     } 
    } 

    void Function2() 
    { 
     if (tokenSource != null) 
     { 
      tokenSource.Cancel(); 
      tokenSource.Dispose(); 
      tokenSource = null; 
     } 
    } 

, 또한 내가 얼마나 확실하지 않다 가능한 한 번만 시작할 수 있으므로 completionTask이 이미 시작되었습니다. 어떤 이유로 든 Function이 순차적으로 또는 여러 스레드에 의해 호출 되더라도 completionTask은 로컬 변수이므로 아무런 문제가 발생하지 않습니다.

원인에 대한 의견이 있으십니까?

+0

작업이 완료되었는지 확인하는 속성 또는 메서드가 있습니다. https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.completedtask(v=vs.110).aspx –

+0

조건 1과 조건 2가 모두 맞으면 시도해 볼 수있는 것처럼 보입니다. completionTask를 두 번 시작합니다. – user6144226

+1

제쳐두고, 일반적인 합의는 [작업 생성자는 사용하지 않아야합니다] (http://blog.stephencleary.com/2014/05/a-tour-of-task-part-1-constructors.html) . –

답변

0

나는 이것이 여러 함수 호출에 걸쳐 적용되기 때문에 cancellationToken의 경쟁 조건이라고 생각합니다. 이와 같이 function2 또는 동일한 함수에 대한 다른 호출에 의해 취소 된 작업을 시작할 수 있습니다.

+0

안녕하세요, 이러한 문제를 일으킬 수있는 일련의 이벤트를 제공 할 수 있습니까? – markusian

+0

난 그냥 루프에서 10x 번 함수를 실행합니다. 이상하게도 나는 이것을 Fiddle에서 재현 할 수 없었다. https://dotnetfiddle.net/Widget/2sstvm – user6144226

+0

@markusian 나는 실제로 당신이 어디서나이 작업을 기다리고 있지 않다는 것을 아주 좋아하는 것을 발견한다. – user6144226

관련 문제