티스토리 뷰

목차

    반응형

    예전에 회사에서 만들었던 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

    반응형