[WPF] 공공데이터 포털 API 이용 클라이언트 구현 Part 3

이미지
그룹핑 ListViewItem 그룹핑 할 수 있습니다. 먼저 CheckBox에 Checked 이벤트를 통해 그룹핑을 추가하고 RemoveChecked 이벤트를 통해 그룹핑을 제거 할 수 있도록 CheckBox를 선언 합니다. 1: <!-- Group CheckBox --> 2: <CheckBox Grid.Column="0" 3: Grid.Row="0" 4: Checked="AddGrouping" 5: Unchecked="RemoveGrouping">Group by Name</CheckBox> 그룹 스타일 선언 GroupStyle 속성에 ContainerStyle 속성을 이용해 Style을 지정 합니다. Expander 컨트롤을 이용해 아파트명과 그룹 아이템의 개수를 Expander Header에 표시 하도록 ControlTemlate를 선언 합니다. 1: <!-- Group Style --> 2: <ListView.GroupStyle> 3: <GroupStyle> 4: <GroupStyle.ContainerStyle> 5: <Style TargetType="{x:Type GroupItem}"> 6: <Setter Property="Margin" Value="0,0,0,5" /> 7: <Setter Property="Te...

[C#] Parallel Invoke를 이용한 병렬 작업 실행(암시적 Task 생성)

아래 샘플 코드는 msdn에서 참고한 코드 입니다.
(https://docs.microsoft.com/ko-kr/dotnet/standard/parallel-programming/how-to-use-parallel-invoke-to-execute-parallel-operations)


샘플 코드를 먼저 보여드린 후 결과를 토대로 설명 하겠습니다.


샘플 코드의 시나리오

  1. 웹 사이트에서 .txt 파일을 다운로드
  2. 다운로드 한 .txt 파일의 문자열을 분할
  3. 분할 된 문자열 배열에서 병렬로 실행할 작업 등록(GetCountForWord, GetMostCommonWords, GetLongesWord)
  4. 별렬 작업 실행


  • 별렬로 실행 할 함수 생성
1:  private static void GetCountForWord(string[] words, string term)  
2:  private static void GetMostCommonWords(string[] words)  
3:  private static string GetLongesWord(string[] words)  

  • Parallel.Invoke() 를 이용한 병렬 작업을 생성
1:   // 소스 배열에서 세가지 작업을 실행  
2:        Parallel.Invoke(() =>  
3:          {  
4:            Console.WriteLine("Begin first task...");  
5:            GetLongesWord(words);  
6:          },  
7:          () =>   
8:          {  
9:            Console.WriteLine("Begin second task...");  
10:            GetMostCommonWords(words);  
11:          },  
12:          () =>  
13:          {  
14:            Console.WriteLine("Begin third task...");  
15:            GetCountForWord(words, "sleep");  
16:          }  
17:        ); //close parallel.invoke  


  • 실행



등록된 메서들이 모두 실행된 결과 입니다. 실행된 메서드들은 쓰레드 풀에서 각각 실행되기에 순서가 보장되지 않아 first, second, third가 순서대로 출력되었지만 다시 실행하면 또 다른 순서대로 출력 됩니다. Task2, Task1, Task3 순서로 출력되는 걸 보면 아시겠죠?^^

- 정리

  • 암시적으로 Task를 생성하여 실행 할 때는 Parallel.Invoke()를 사용
  • 등록된 작업은 쓰레드 풀에서 실행
  • 순서 보장을 할 수 없음

# 전체 소스

1:  /// <summary>  
2:    /// 암시적으로 작업 만들기 및 실행  
3:    /// Parallel.Invoke를 사용하여 병렬 작업 실행  
4:    /// </summary>  
5:    class Program  
6:    {  
7:      static void Main(string[] args)  
8:      {  
9:        string[] words = CreateWordArray(@"http://www.gutenberg.org/files/54700/54700-0.txt");  
10:        #region 병렬 작업 만들기 및 실행  
11:        // 소스 배열에서 세가지 작업을 실행  
12:        Parallel.Invoke(() =>  
13:          {  
14:            Console.WriteLine("Begin first task...");  
15:            GetLongesWord(words);  
16:          },  
17:          () =>   
18:          {  
19:            Console.WriteLine("Begin second task...");  
20:            GetMostCommonWords(words);  
21:          },  
22:          () =>  
23:          {  
24:            Console.WriteLine("Begin third task...");  
25:            GetCountForWord(words, "sleep");  
26:          }  
27:        ); //close parallel.invoke  
28:        Console.WriteLine("Returned from Parallel.Invoke");  
29:        #endregion  
30:        Console.WriteLine("Press any key to exit");  
31:        Console.ReadKey();  
32:      }  
33:      #region HelperMethods  
34:      /// <summary>  
35:      /// 단어 배열에서 지정된 단어를 찾는다.  
36:      /// </summary>  
37:      /// <param name="words"></param>  
38:      /// <param name="term"></param>  
39:      private static void GetCountForWord(string[] words, string term)  
40:      {  
41:        var findWord = from word in words  
42:                where word.ToUpper().Contains(term.ToUpper())  
43:                select word;  
44:        Console.WriteLine($@"Task 3 -- The word ""{term}"" occurs {findWord.Count()} times.");  
45:      }  
46:      /// <summary>  
47:      /// 단어의 길이가 6 초과되는 단어를 그룹화 하여 그룹 개수를 내림차순으로 정렬한 결과를 10개를 조회 한다.  
48:      /// </summary>  
49:      /// <param name="words"></param>  
50:      private static void GetMostCommonWords(string[] words)  
51:      {  
52:        var frequencyOrder = from word in words  
53:                   where word.Length > 6  
54:                   group word by word into g  
55:                   orderby g.Count() descending  
56:                   select g.Key;  
57:        var commonWords = frequencyOrder.Take(10);  
58:        StringBuilder sb = new StringBuilder();  
59:        sb.AppendLine("Task 2 -- The most common words are:");  
60:        foreach (var v in commonWords)  
61:        {  
62:          sb.AppendLine(" " + v);  
63:        }  
64:        Console.WriteLine(sb.ToString());  
65:      }  
66:      /// <summary>  
67:      /// 가장 긴 길이의 단어를 가져옵니다.  
68:      /// </summary>  
69:      /// <param name="words"></param>  
70:      /// <returns></returns>  
71:      private static string GetLongesWord(string[] words)  
72:      {  
73:        var longestWord = (from w in words  
74:                  orderby w.Length descending  
75:                  select w).First();  
76:        Console.WriteLine($"Task 1 -- The longest word is {longestWord}.");  
77:        return longestWord;  
78:      }  
79:      /// <summary>  
80:      /// 동기적으로 웹 페이지의 문자열을 다운로드 합니다.  
81:      /// </summary>  
82:      /// <param name="uri"></param>  
83:      /// <returns></returns>  
84:      static string[] CreateWordArray(string uri)  
85:      {  
86:        Console.WriteLine($"Retrieving from {uri}");  
87:        // 웹 페이지 문자열을 다운로드   
88:        string s = new WebClient().DownloadString(uri);  
89:        // 문자열을 단어 배열로 분리  
90:        return s.Split(  
91:          new char[] { ' ', '\u000A', ',', '.', ';', ':', '-', '_', '/' },  
92:          StringSplitOptions.RemoveEmptyEntries);  
93:      }  
94:      #endregion  
95:    }  

댓글

이 블로그의 인기 게시물

[C#] Task 완료 시 다른 Task를 자동으로 수행

[C#] 태스크(Task)가 완료될 때 까지 대기하여 결과를 얻는 방법

[C#] 명시적으로 Task 생성 및 실행