본문 바로가기
C++ 200제/코딩 IT 정보

C# 비동기 프로세스 제어 소스, async task process

by vicddory 2019. 5. 5.
반응형

예전에 회사에서 만들었던 C# 비동기 테스트 소스입니다. cmd.exe 직접 제어하여 콘솔에 명령어 날리고 응답 값을 바당 뿌려주는 소스인데요. 아래에도 소개하겠지만, static async Task<string> DoSignAsync() 함수를 꾸며서 원하는 대로 수정하여 사용할 수 있습니다.


큰 흐름상, C# ProcessStartInfo 객체를 이용해 프로세스를 제어하고, async DoAction() 함수로 비동기 함수 호출, 종료 등 큰 흐름을 잡습니다. 세부적인 task 동작은 위에서 언급한 DoSignAsync 함수에서 담당합니다.

◆ 전체 C# 소스 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
namespace ProcessAsyncExam
{
    class Program
    {
        static private string PROCESS_NAME_CMD = "cmd.exe";
        static ProcessStartInfo psi = null;
        static Process proc = null;
 
        static void Main(string[] args)
        {
            psi = new ProcessStartInfo();
            psi.UseShellExecute = false;
            psi.CreateNoWindow = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardError = true;
 
            proc = new Process();
            proc.EnableRaisingEvents = true;
 
            proc.ErrorDataReceived += (object sending_process, DataReceivedEventArgs e) =>
            {
                if (e.Data != null)
                {
                    Console.WriteLine(e.Data.ToString());
                }
            };
 
            proc.OutputDataReceived += (object sending_process, DataReceivedEventArgs e) =>
            {
                if (e.Data != null)
                {
                    Console.WriteLine(e.Data.ToString());
                }
            };
 
            DoAction();
 
            Console.ReadLine();
        }
 
        static async void DoAction()
        {
            psi.FileName = PROCESS_NAME_CMD;
            psi.WorkingDirectory = "C:\\";
 
            proc.StartInfo = psi;
            proc.Start();
 
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();
 
            await DoSignAsync();
 
            proc.CancelOutputRead();
            proc.CancelErrorRead();
            proc.Close();
        }
 
        static async Task<string> DoSignAsync()
        {
            string console_cmd = "dir";
 
            proc.StandardInput.Write(console_cmd + Environment.NewLine);
            proc.StandardInput.Flush();
 
            await Task.Delay(20);
 
            for (int j = 0; j < 10; j++)
            {
                await Task.Delay(1000); // 비동기 작업이라 결과가 언제 날아올지 몰라 임의로 대기 시간 할당
 
                Console.WriteLine(j);
            }
 
            await Task.Delay(1000);
 
            proc.StandardInput.Close();
 
            return null;
        }
    }
}
cs


하나씩 살펴볼게요.

◆ ProcessStartInfo 객체

cmd.exe 실행하기 위한 객체입니다. C# ProcessStartInfo를 통해 제어할 수 있어요.


44~45번 라인 : PROCESS_NAME_CMD (cmd.exe) 커맨드창의 시작 위치를 C:\로 설정합니다.


◆ Process 객체

이 소스에서는 cmd.exe를 가리킨다고 보면 되겠습니다. EnableRaisingEvents 값을 true로 바꿔 이벤트 발생을 활성화합니다.


28~34번 라인 : 프로세스 제어 과정에서 발생한 에러를 출력합니다.


36~42번 라인 : 커맨드창에 출력되는 메시지를 비주얼스튜디오 콘솔에 출력합니다. 예를 들어, 커맨드창에 A를 입력하면 B라는 응답 값이 나옵니다. 여기서 B를 콘솔에 찍어주는 것이죠.


C# 비동기 프로세스 제어 소스, async task process


◆ DoAction 함수

프로시저 설정, 시작, 비동기 읽기, 비동기 에러 출력, 비동기 함수 실행, 프로시저 종료입니다. 위에서부터 순서대로 읽는 것 그대로입니다.


BeginOutputReadLine 함수 <-> CanCelOutputRead 함수는 한 쌍으로 사용합니다. 비동기 읽기를 실행만 해놓고 cancel 함수 호출 안 하면 프로세스 점유 상태가 끝나지 않습니다.


◆ Task<string> DoSignAsync 함수

타스크 string 중 string이 실제 cmd.exe 콘솔창에 입력되는 메시지입니다. 사용자 입력 부분이죠. input data 입니다. output은 29번 라인에 설정해 두어서 이 함수에 별도로 구성할 필요는 없어요.


이 함수는 제가 테스트하려고 만든 소스 중 일부입니다. 민감한 건 다 삭제하고 껍데기만 남아 있네요. 커맨드 창 프로세스를 제어하실 때, 이 함수를 적절히 꾸미면 됩니다.


c# task 비동기 함수


이 정도로 C# 비동기 프로세스 제어 소스 예제 소개를 마치겠습니다. 이해가 안 되는 부분이 있다면 댓글로 남겨주세요. 최대한 자세히 알려드리겠습니다.



관련 글


C# 비동기 Async, 소켓 서버, 함수 소스 (Socket network)


C# TASK 7가지 사용법, C# 스레드는 이제 그만


C# 외부 프로그램 (프로세스) 실행하기 (Process Start)



ⓒ written by vicddory

반응형