相关疑难解决方法(0)

如何同步运行异步Task <T>方法?

我正在学习async/await,并遇到了需要同步调用异步方法的情况.我怎样才能做到这一点?

异步方法:

public async Task<Customers> GetCustomers()
{
    return await Service.GetCustomersAsync();
}
Run Code Online (Sandbox Code Playgroud)

正常使用:

public async void GetCustomers()
{
    customerList = await GetCustomers();
}
Run Code Online (Sandbox Code Playgroud)

我尝试过使用以下内容:

Task<Customer> task = GetCustomers();
task.Wait()

Task<Customer> task = GetCustomers();
task.RunSynchronously();

Task<Customer> task = GetCustomers();
while(task.Status != TaskStatus.RanToCompletion)
Run Code Online (Sandbox Code Playgroud)

我也从这里尝试了一个建议,但是当调度程序处于暂停状态时它不起作用.

public static void WaitWithPumping(this Task task) 
{
        if (task == null) throw new ArgumentNullException(“task”);
        var nestedFrame = new DispatcherFrame();
        task.ContinueWith(_ => nestedFrame.Continue = false);
        Dispatcher.PushFrame(nestedFrame);
        task.Wait();
}
Run Code Online (Sandbox Code Playgroud)

以下是调用的异常和堆栈跟踪RunSynchronously:

System.InvalidOperationException

消息:可能无法在未绑定到委托的任务上调用RunSynchronously.

InnerException:null

资料来源:mscorlib …

c# asynchronous async-await c#-5.0

606
推荐指数
16
解决办法
36万
查看次数

同步调用异步方法

我有一个async方法:

public async Task<string> GenerateCodeAsync()
{
    string code = await GenerateCodeService.GenerateCodeAsync();
    return code;
}
Run Code Online (Sandbox Code Playgroud)

我需要从同步方法中调用此方法.

如何在不必复制GenerateCodeAsync方法的情况下执行此操作以使其同步工作?

更新

然而找不到合理的解决方案

但是,我看到HttpClient已经实现了这种模式

using (HttpClient client = new HttpClient())
{
    // async
    HttpResponseMessage responseAsync = await client.GetAsync(url);

    // sync
    HttpResponseMessage responseSync = client.GetAsync(url).Result;
}
Run Code Online (Sandbox Code Playgroud)

c# asp.net asynchronous task-parallel-library async-await

216
推荐指数
7
解决办法
21万
查看次数

从非异步代码调用异步方法

我正在更新具有在.NET 3.5中构建的API表面的库.因此,所有方法都是同步的.我无法更改API(即,将返回值转换为Task),因为这将要求所有调用者都更改.所以我留下了如何以同步方式最好地调用异步方法.这是在ASP.NET 4,ASP.NET Core和.NET/.NET Core控制台应用程序的上下文中.

我可能不够清楚 - 情况是我现有的代码不是异步识别的,我想使用新的库,如System.Net.Http和仅支持异步方法的AWS SDK.所以我需要缩小差距,并且能够拥有可以同步调用的代码,然后可以在其他地方调用异步方法.

我已经做了很多阅读,并且有很多次这已经被问及并回答了.

从非异步方法调用异步方法

同步等待异步操作,以及为什么Wait()在这里冻结程序

从同步方法调用异步方法

如何同步运行异步Task <T>方法?

同步调用异步方法

如何从C#中的同步方法调用异步方法?

问题是大多数答案都不同!我见过的最常见的方法是使用.Result,但这可能会死锁.我已经尝试了以下所有内容,并且它们可以工作,但我不确定哪种方法可以避免死锁,具有良好的性能,并且可以很好地运行运行时(在尊重任务调度程序,任务创建选项等方面) ).有明确的答案吗?什么是最好的方法?

private static T taskSyncRunner<T>(Func<Task<T>> task)
    {
        T result;
        // approach 1
        result = Task.Run(async () => await task()).ConfigureAwait(false).GetAwaiter().GetResult();

        // approach 2
        result = Task.Run(task).ConfigureAwait(false).GetAwaiter().GetResult();

        // approach 3
        result = task().ConfigureAwait(false).GetAwaiter().GetResult();

        // approach 4
        result = Task.Run(task).Result;

        // approach 5
        result = Task.Run(task).GetAwaiter().GetResult();


        // approach 6
        var t = task();
        t.RunSynchronously();
        result = t.Result;

        // approach 7
        var t1 = task();
        Task.WaitAll(t1); …
Run Code Online (Sandbox Code Playgroud)

c# asp.net multithreading asynchronous task-parallel-library

62
推荐指数
2
解决办法
4万
查看次数