C#: Использование асинхронных методов

145
18 октября 2019, 05:00

Обычно я использую следующий асинхронный код:

private async Task<string> Method()
    {
        var promise = new TaskCompletionSource<string>();
        await Task.Run(() =>
        {
            string answer = null;
            //тут что то происходит
            promise.SetResult(answer);
        });
        var result = await promise.Task;
        return result;
    }

И вызываю его так: await Method();

Если мне нужно записать ответ метода в переменную, я делаю это так:

string x = await Method();

Но недавно я нашёл вот этот код:

public static Task TryInvokeMethodAsync(Action func)
    {
        var tcs = new TaskCompletionSource<Task>();
        Task.Factory.StartNew(() =>
        {
            try
            {
                func.Invoke();
                tcs.SetResult(null);
            }
            catch (OperationCanceledException)
            {
                tcs.SetCanceled();
            }
            catch (System.Exception ex)
            {
                tcs.SetException(ex);
            }
        });
        return tcs.Task;
    }

Который вызывается так:

TryInvokeMethodAsync(() => AnyMethod());

То есть с помощью этого метода можно любой метод вызвать асинхронно. Но как получить от него ответ (например, тот же string)? TryInvokeMethodAsync возвращает Task, если пытаться получить от него ответ так:

var x = TryInvokeMethodAsync(() => AnyMethod());

А через await он вообще не вызывается, даже если сделать его async.

И вообще, правильный ли асинхронный код я использую?

P.S. как правильно использовать try-catch в первом методе, который указан в самом начале?

Answer 1

Почему бы не так

private async Task<string> Method()
{
    return await Task.Run(() =>
    {
        string answer = null;
            //тут что то происходит
        return answer;
    }); 
}

или так

public static async Task TryInvokeMethodAsync(Action func)
{   
    await Task.Run(() =>
    {   
        func.Invoke();      
    }); 
}

Или даже так

public static async Task<T> TryInvokeMethodAsync<T>(Func<T> func)
{   
    return await Task.Run(() =>
    {
        return func.Invoke();
    });
}

А может и так (хотя тут уже непонятно зачем :))

public static async Task<T> TryInvokeMethodAsync<T>(Func<Task<T>> func)
{
    return await func();
}
READ ALSO
C# доступ к свойству устройства через WMI

C# доступ к свойству устройства через WMI

уважаемые программистыПрошу помочь, ибо я уже путаюсь в изученном и найденном материале, а поставленную перед собой задачу решить охота

151
Vuforia wep api и работа с ним

Vuforia wep api и работа с ним

При отправке запросов на облако vuforia, необходимо составлять Autorization такого вида:

129
Path.Combine игнорирует первый аргумент

Path.Combine игнорирует первый аргумент

Есть переменная folder, в которой записан путь до папки приложения, его значение - D:\Programming\C#\SKProCH's Launcher\bin\Debug\В другой переменной присваивается...

112
C# Как создать команду для бота

C# Как создать команду для бота

все никак не мог придумать название моей проблеме, думаю, сейчас тоже не особо вышлоПишу бота на C# для ВК используя библиотеку VKNet

191