C# 동기/비동기 처리


이것은 검색 기능의 예입니다.

private async Task fncLoadList()
{
    try
    {
        DataTable dtInput = new DataTable("inputData");
        dtInput.addColumns("hsptKey,agrgYm");

        DataRow drInput = dtInput.NewRow();
        drInput("hsptKey") = "...";    // TODO
        drInput("agrgYm") = DateTime.Now.ToString("yyyyMMdd");  // TODO
        dtInput.Rows.Add(drInput);

        MepsTran mepsTran = new MepsTran();
        mepsTran.Controller = "...";
        mepsTran.InDs.Add("inputData", dtInput);
        mepsTran.OutDs.Add("dtResult", "resultData");

        MDataSet resultData = await mepsTran.tran();
        if (resultData.getStatusCode() < 0)
        {
            XtraMessageBox.Show(resultData.getErrMsg(), resultData.getErrCode(), MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        dsRtrv.Tables("dtAgrgType").fill(resultData.getDataTable("dtResult"));
    }
    catch (Exception ex)
    {
        XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

검색 기능의 또 다른 예.

private async Task fncLoadComn()
{
    try
    {
        LoadComn loadComn = new LoadComn();

        // 설정
        loadComn.addRow("dtBA001", "BA001", "");   // 진료구분 BA001
        loadComn.addRow("dtBA002", "BA002", "");   // 보험유형 BA002
        ... 생략

        // 조회
        await loadComn.rtrvData();

        loadComn.setDataTable(cmbMedDvsn, "dtBA001", "O");
        loadComn.setDataTable(cmbInsType, "dtBA002", "C");
        ... 생략
    }
    catch (Exception ex)
    {
        XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

위의 기능을 간단하게 표현했습니다.

private async Task fncLoadList()
{
    // fncLoadList#await전
    // MDataSet resultData = await mepsTran.tran();
    // fncLoadList#await후
}

private async Task fncLoadComn()
{
    // fncLoadComn#await전
    // await loadComn.rtrvData();
    // fncLoadComn#await후
}

비동기 처리

private async Task fncFormOnload()
{
    this.fncLoadList();
    this.fncLoadComn();

    this.fncLoadInit();
}

> fncLoadList#await 전 > fncLoadComn#await 전 > fncLoadInit > fncLoadList#await 후 또는 fncLoadComn#await 후

fncLoadList#await 이후와 fncLoadComn#await 이후 둘의 실행 순서는 알 수 없다(상황에 따라 다름).

그러나 after fncLoadList#await가 fncLoadComn#await보다 먼저 실행된다고 가정합니다.


동기식 처리

private async Task fncFormOnload()
{
    await this.fncLoadList();
    await this.fncLoadComn();

    this.fncLoadInit();
}

> fncLoadList#await 전 > fncLoadList#await 후 > fncLoadComn#await 전 > fncLoadComn#await 후 > fncLoadInit

핸들러가 this.fncLoadList의 await로 인해 fncFormOnload 함수로 반환되었지만

await this.fncLoadList()의 await가 포착되어 대기합니다.

그런 다음 MDataSet resultData = await mepsTran.tran(); this.fLoadList의. 문은 서버에서 결과를 반환하기 때문에

fncLoadList#await를 실행하고 fncLoadList의 결과 값을 수신한 후,

다음 문은 await this.fncLoadComn(); 지나갈 것이다


비동기 처리 ver.2

private async Task fncFormOnload()
{
    Task() tasks = new Task(2);
    tasks(0) = this.fncLoadComn();
    tasks(1) = this.fncLoadList();

    await tasks(0);
    await tasks(1);

    this.fncLoadInit();
}

> fncLoadList#await 전 > fncLoadComn#await 전 > fncLoadList#await 후 > fncLoadComn#await 후 > fncLoadInit

DB로부터 List와 Comn의 결과 값을 모두 얻은 후 초기화 함수 fncLoadInit를 실행하고 싶다면,

대기 작업으로 이를 수행할 수 있습니다.

위의 동기 처리 예에서는 실행 함수와 대기가 함께 있고,

최종 결과가 나올 때까지 다음 문장을 실행할 수 없었습니다.

이 예제에서는 실행 함수를 태스크로 받고 태스크를 기다리기 전 부분을 비동기적으로 처리합니다.

비동기적으로 실행되는 함수가 완료된 후 실행할 특정 함수를 사용자 지정할 수 있습니다.


비동기 처리 ver.3

private async Task fncFormOnload()
{
    this.onLoadInit();

    Task() tasks = new Task(2);
    tasks(0) = this.fncLoadComn();
    tasks(1) = this.fncLoadList();

    await Task.WhenAll(tasks);
    // await Task.WhenAll(this.fncLoadComn(), this.fncLoadList());

    this.fncLoadInit();
}

> fncLoadList#await 전 > fncLoadComn#await 전 > fncLoadList#await 후 > fncLoadComn#await 후 > fncLoadInit

WhenAll이라는 명령을 사용하여 버전 2 비동기 처리를 처리하는 예입니다.

WhenAll은 매개변수로 받은 비동기 함수에서 작업 결과를 수집하고 처리합니다.

비동기 함수가 완료되기 전에 Task.WhenAll 전에 기다리지 않으면

fncLoadInit가 실행됩니다.

Task.WhenAll 전에 대기가 없는 경우,

> fncLoadList#await 전 > fncLoadComn#await 전 > fncLoadInit > fncLoadList#await 후 > fncLoadComn#await 후