簡體   English   中英

C#如何等待異步任務,直到它指示繼續

[英]C# How to await async task until it indicates to proceed

我有一個C#方法,可以循環調用多次外部Web服務。 我需要在另一個線程中異步調用它。

但是調用者進程必須等到異步線程滿足某個條件為止-這種條件發生在循環迭代完成之前。

請提出一個C#代碼示例,該示例描述如何等待直到異步代碼塊指示已滿足特定條件,以便主進程可以繼續執行而無需等待循環完成。

我的代碼:

..
List<MyObject> objList = GetObjects();
int counter = 0;
await Task.Factory.StartNew(() =>
{
    foreach (MyObject obj in objList)
    {
        counter++;
        CallExtWebSvc(obj);
        if (counter == 1)
        {
            // return an indication that main process can proceed.
        }
    }
});

// Do other stuff...

您可能會像火災一樣執行方法而忘記了,然后等待TaskCompletionSource。 該TaskCompletionSource被提供給調用webservice作為參數的方法。 然后,該方法會在某個時刻在TaskCompletionSource上設置結果。

這是一個示例代碼段:

        public async Task DoWebserviceStuffAsync(TaskCompletionSource<bool> taskCompletionSource)
        {
            for (int i = 0; i < 10; i++)
            {
                //your webservice call
                await Task.Delay(5000);

                //some condition
                if (i == 1)
                {
                    //after setting this your CallingMethod finishes 
                    //waiting the await taskCompletionSource.Task;
                    taskCompletionSource.TrySetResult(true);
                }
            }
        }

        private async Task CallerMethod()
        {
            var taskCompletionSource = new TaskCompletionSource<bool>();

            //call method without await
            //care: You cannot catch exceptions without await
            DoWebserviceStuffAsync(taskCompletionSource);

            //wait for the DoWebserviceStuffAsync to set a result on the passed TaskCompletionSource
            await taskCompletionSource.Task;
        }

如果要避免發生“失火”的危險,或者還需要等待完整的操作完成,則可以返回兩個任務(Task,Task) (C#v7語法)。 呼叫者將依次等待兩個任務。

public async Task Caller()
{
    var (partOne,partTwo) = DoSomethingAsync();

    await partOne;
    //part one is done...

    await partTwo;
    //part two is done...
}

public (Task,Task) DoSomethingAsync()
{
    var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
    return (tcs.Task, DoWork(tcs));
}

public async Task DoWork(TaskCompletionSource<bool> tcs)
{
    List<MyObject> objList = GetObjects();
    int counter = 0;
    await Task.Run(() =>
    {
        foreach (MyObject obj in objList)
        {
            counter++;
            CallExtWebSvc(obj);
            if (counter == 1)
            {
                // return an indication that main process can proceed.
                tcs.SetResult(true);
            }
        }
    });

    // Do other stuff...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM