2015-01-26 2 views
0

지도를 생성하려고합니다. 나는 접근 가능하고 접근 할 수없는 부분을 나타내는 2D 불린 배열을 만들었다. 이제 캔버스에 여러 개의 직사각형을 그리려하고 있습니다. 내가 뭘 잘못하고 있는지 전혀 모르겠다.다중 작업에서 캔버스에 액세스하기

private void GenerateMapParallel(Canvas cMap) 
{ 
    cMap.Children.Clear(); 

    var task1 = Task.Factory.StartNew(() => Generate(0, 330, cMap)); 
    var task2 = Task.Factory.StartNew(() => Generate(331, 660, cMap)); 

    Task.WaitAll(task1, task2); 
} 

private void Generate(int start, int stop, Canvas cMap) 
{ 

    for (int i = start; i < stop; i++) 
    { 
     for (int j = 0; j < Map.instance.height; j++) 
     { 
      if (Map.instance.map[i, j] == false) 
      { 
       if(cMap.Dispatcher.CheckAccess()) 
       { 
        cMap.Children.Add(new Rectangle() { Width = 1, Height = 1, Margin = new Thickness(i, j, 0, 0), Fill = Brushes.Gray }); 
       } 
       else 
       { 
        cMap.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { cMap.Children.Add(new Rectangle() { Width = 1, Height = 1, Margin = new Thickness(i, j, 0, 0), Fill = Brushes.Gray }); })); 

       } 

      } 
     } 
    } 
} 

어딘가에 무한 루프처럼 응용 프로그램이로드되지 않습니다. Task1은 첫 번째 상위 절반을 생성하고 Task2는 하위 절반을 생성합니다. 어떤 아이디어를 더 잘하는 방법? 나는 TPL에 새로운 사람입니다.

+0

와 동 기적으로 발송자에 비동기 작업을 호출 대신하는 것입니다 루프는 병렬로 변환 할 수 있습니다 .ForEach 루프 – Sievajet

+0

사용중인 .Net 버전은 무엇입니까? – i3arnon

+0

나는 각각에 대해 병렬을 사용할 수 있지만 작업으로해야한다고 알고 있습니다. .Net 4,5 – Safiron

답변

1

Dispatcher.Invoke으로 UI 스레드에서 작업을 호출하는 중 Task.Wait을 호출하여 UI 스레드를 차단하고 있습니다. 작업은 UI 스레드가 사용 가능할 때까지 대기하며 UI 스레드는 작업이 완료 될 때까지 대기합니다. 교착 상태가 발생합니다.

당신은 await 비동기 기다려야한다 :

private async Task GenerateMapParallel(Canvas cMap) 
{ 
    cMap.Children.Clear(); 

    var task1 = Task.Factory.StartNew(() => Generate(0, 330, cMap)); 
    var task2 = Task.Factory.StartNew(() => Generate(331, 660, cMap)); 

    await Task.WhenAll(task1, task2); 
} 

교착 상태를 깰 수있는 또 다른 방법 것은 Dispatcher.BeginInvoke

+0

작동하지만 전체 프로세스가 비 병렬 솔루션보다 오래 걸립니다. 나는 Invoking에 그것의 할 것 같아? 또한 GenerateMapParallel (..) 메서드를 호출 할 때 "호출이 대기 중이 아니며 ... 비동기를 사용해야합니다."어떻게해야합니까? " – Safiron

+0

@Safiron 매우 가능성 있음. dispatcher가 단일 스레드를 사용하고 나머지는 무시할 수 있기 때문에 실제로는 아무 것도 병렬 처리하지 않습니다. – i3arnon

+0

감사합니다. 어쨌든 고맙습니다. – Safiron

관련 문제