Task that has no timeout

I have a simple task using TPL. It waits 10 seconds to execute and returns true / false.

var checkCFOPTask = Task.Run(() => CheckCFOPExists());
checkCFOPTask.Wait(TimeSpan.FromSeconds(10));
if (checkCFOPTask.Result)
{

}
else
{

}

      

The problem is my code is stuck inside the if statement.

if (checkCFOPTask.Result)

      

Every time I pause the debugger, it is still waiting in line over the specified line of code. This happened for the first time. Ideally, it should return true / false within 10 seconds.

Following are the function definitions -

CheckCFOExists: Completed by this task.

private bool CheckCFOPExists()
{
    bool found = false;

    try
    {
        while (!found)
        {
            try
            {
                if (ieDriver.FindElement(By.Id("popup_message")).Text == "Não existem itens para realizar o rateio.")
                {
                    ResetInvoiceSearchScreen();
                    break;
                }
            }
            catch (Exception ex)
            {

            }

            try
            {
                if (arrCFOPList.Contains(ieDriver.FindElement(By.Id("vendorNF.cfopOperCode")).GetAttribute("value")))
                {
                    found = true;
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
    catch (Exception ex)
    {

    }
    return found;
}

      

ResetInvoiceSearchScreen: Done in the above function

private void ResetInvoiceSearchScreen()
{
    try
    {
        ieDriver.FindElement(By.Id("popup_ok")).Click();
        ieDriver.FindElement(By.Id("ltmCnpjCpf")).Clear();
        ieDriver.FindElement(By.Id("notaFiscalNbr")).Clear();
        ieDriver.FindElement(By.Id("inbNotaFiscalId")).Clear();
        ieDriver.FindElement(By.Id("seriesFrmCd")).Clear();
    }
    catch (Exception ex)
    {

    }
}

      

Is there anything else that is needed for the function to work properly? Please let me know if I can provide more details.

Edit

I see the following message for checkCFOPTask.Result

in the immediate Visual Studio window -

Id = Cannot evaluate expression because the code of the current method is optimized., Status = Cannot evaluate expression because the code of the current method is optimized., Method = Cannot evaluate expression because the code of the current method is optimized., Result = Cannot evaluate expression because the code of the current method is optimized.

      

+3


source to share


2 answers


It looks like you will need to add timeout support to the method you are calling, because if it doesn't find what it is looking for, it will work forever.

The easiest way to do this is by passing a method CancellationToken

. You should also decompose your testing code into a separate method that returns bool.

Also note that you have a busy cycle that is generally not recommended when polling! It is better to enter a little sleep when interviewing if the subject you are interviewing is not available. (Note: Polling is generally not a good approach if you have a better way to test something, but it doesn't look like what you can use here, so you will need to do a survey.)

You can write your method like this (I omitted the code that polls what you are looking for in order to focus on other logic):



private bool CheckCFOPExists(CancellationToken cancel)
{
    TimeSpan retryDelay = TimeSpan.FromMilliseconds(500);

    while (true)
    {
        if (tryToFindTheThing()) // Blocking call.
            return true;

        if (cancel.WaitHandle.WaitOne(retryDelay))
            return false;
    }
}

bool tryToFindTheThing()
{
    return false;  // Your implementation goes here.
}

      

Then, to call it and have a 10 second timeout, you would do something like this (a compiled console application):

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        static void Main()
        {
            var test = new Program();

            // Create a cancellation token source that cancels itself after 10 seconds:
            var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(10));

            // Create and run the task:

            var sw = Stopwatch.StartNew();
            var checkCFOPTask = Task.Run(() => test.CheckCFOPExists(cancellation.Token));

            Console.WriteLine("Waiting for task to finish.");
            Console.WriteLine($"Task returned: {checkCFOPTask.Result} after {sw.ElapsedMilliseconds} ms");
        }

        private bool CheckCFOPExists(CancellationToken cancel)
        {
            TimeSpan retryDelay = TimeSpan.FromMilliseconds(500);

            while (true)
            {
                if (tryToFindTheThing()) // Blocking call.
                    return true;

                if (cancel.WaitHandle.WaitOne(retryDelay))
                    return false;
            }
        }

        bool tryToFindTheThing()
        {
            return false;  // Your implementation goes here.
        }
    }
}

      

+1


source


Before using the result, you need to check if your task has actually completed using Task.IsCompleted .



if (checkCFOPTask.IsCompleted && checkCFOPTask.Result)

      

0


source







All Articles