CS4010 Как преобразовать асинхронное лямбда-выражение в тип делегата TaskAction

Я получаю следующую ошибку

Ошибка CS4010 Не удается преобразовать асинхронное лямбда-выражение в тип делегата TaskAction. Асинхронное лямбда-выражение может возвращать void, Task или Task, ни один из которых не может быть преобразован в TaskAction.

Моя функция выглядит так:

public async void GetLastKnownUpdateStatus(string UUIDStr, short ClientId)
{
    UpdateStatusInfo x = new UpdateStatusInfo();
    if (Execution.WaitForTask(async (canceltoken) => { x = await GetLastKnownUpdateStatus(UUIDStr, ClientId); return true; }) > Execution.WAIT_TIMEOUT)
    {
        Output.WriteLine("GetLastKnownUpdateStatus: "+ x.State.ToString());
    }
}

Этот метод вызывает следующую функцию:

public Task<UpdateStatusInfo> GetLastKnownUpdateStatus(string uniqueUpdateID, short clientID)
{
    return GetLastKnownUpdateStatus(uniqueUpdateID, clientID, null);
}

приветствуется любая помощь

Execution.WaitForTask происходит от класса Vector.CANoe.Threading и определяется Vector следующим образом

//
// Summary:
//     Executes a task in a separate thread. During the wait, the measurement and simulation
//     are not blocked. Optionally returns failure after a certain timespan.
//
// Parameters:
//   taskAction:
//     A delegate function to execute in a separate task
//
//   maxTime:
//     Optional: maximum time to wait, in milliseconds.
//
// Returns:
//     WAIT_TIMEOUT: if an maxTime was defined and the task did not return within maxTime
//     milliseconds WAIT_ABORTED: if the measurement was stopped during task execution
//     WAIT_EXCEPTION: if an exception occurred in the taskAction delegate WAIT_ILLEGAL_RESULTVALUE:
//     the result provided by the task is <= 0 > 0 any positive result provided by the
//     taskAction delegate (only use numbers > 0 as return values)
//
// Remarks:
//     Be careful: You may not use most of the CANoe API functions in the taskAction.
//     Allowed is: Modifying SystemVariables Using Output.* functions See documentation
//     for details

person Om Choudhary    schedule 31.07.2019    source источник
comment
Было бы действительно полезно, если бы вы переформатировали код, чтобы избежать длинной строки, и предоставить минимально воспроизводимый пример. На данный момент мы не знаем, что такое TaskAction, и он никогда не упоминается в предоставленном вами коде. Мы также не знаем, что такое Execution.WaitForTask. Без всей необходимой информации мы не сможем помочь.   -  person Jon Skeet    schedule 31.07.2019


Ответы (1)


TaskAction не может быть асинхронным выражением. Это должно быть синхронно. Фреймворк CANoe позаботится о том, чтобы он выполнялся в фоновой задаче.

Лучше всего было бы вызвать любой синхронный метод GetLastKnownUpdateStatus, который, наконец, вызывает, прямо как это

public async void GetLastKnownUpdateStatus(string UUIDStr, short ClientId)
{
    UpdateStatusInfo x = new UpdateStatusInfo();
    if (Execution.WaitForTask((canceltoken) => {
          x = GetLastKnownUpdateStatusSync(UUIDStr, ClientId); return true;
        }
    ) > Execution.WAIT_TIMEOUT)
    {
        Output.WriteLine("GetLastKnownUpdateStatus: "+ x.State.ToString());
    }
}

или дождитесь вызова в лямбде:

public async void GetLastKnownUpdateStatus(string UUIDStr, short ClientId)
{
    UpdateStatusInfo x = new UpdateStatusInfo();
    if (Execution.WaitForTask((canceltoken) => { 
          x = GetLastKnownUpdateStatus(UUIDStr, ClientId).ConfigureAwait(false).GetAwaiter().GetResult(); return true;
        }
    ) > Execution.WAIT_TIMEOUT)
    {
        Output.WriteLine("GetLastKnownUpdateStatus: "+ x.State.ToString());
    }
}
person M. Spiller    schedule 31.07.2019
comment
Спасибо, первое решение не сработает, потому что вы не можете преобразовать задачу типа в void. Но ваше второе решение сработало для меня .ConfigureAwait(false).GetAwaiter().GetResult() действительно запутался с этим, не знаю, почему он работает - person Om Choudhary; 01.08.2019