相关疑难解决方法(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万
查看次数

正确使用Task.Run时和async-await时

我想问你关于正确架构何时使用的意见Task.Run.我在WPF .NET 4.5应用程序(使用Caliburn Micro框架)中遇到了滞后的UI.

基本上我在做(非常简化的代码片段):

public class PageViewModel : IHandle<SomeMessage>
{
   ...

   public async void Handle(SomeMessage message)
   {
      ShowLoadingAnimation();

      // Makes UI very laggy, but still not dead
      await this.contentLoader.LoadContentAsync();

      HideLoadingAnimation();
   }
}

public class ContentLoader
{
    public async Task LoadContentAsync()
    {
        await DoCpuBoundWorkAsync();
        await DoIoBoundWorkAsync();
        await DoCpuBoundWorkAsync();

        // I am not really sure what all I can consider as CPU bound as slowing down the UI
        await DoSomeOtherWorkAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

从我阅读/看到的文章/视频中,我知道await async不一定在后台线程上运行,并且需要在后台开始工作,需要等待它Task.Run(async () => …

c# asynchronous task async-await

288
推荐指数
2
解决办法
25万
查看次数

同步调用异步方法

我有一个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万
查看次数

有效地使用ASP.NET Web API的async/await

我试图async/await在我的Web API项目中使用ASP.NET 的功能.我不确定它是否会对我的Web API服务的性能产生任何影响.请在下面找到我的应用程序中的工作流程和示例代码.

工作流程:

UI应用程序→Web API端点(控制器)→Web API服务层中的调用方法→调用另一个外部Web服务.(这里我们有数据库交互等)

控制器:

public async Task<IHttpActionResult> GetCountries()
{
    var allCountrys = await CountryDataService.ReturnAllCountries();

    if (allCountrys.Success)
    {
        return Ok(allCountrys.Domain);
    }

    return InternalServerError();
}
Run Code Online (Sandbox Code Playgroud)

服务层:

public Task<BackOfficeResponse<List<Country>>> ReturnAllCountries()
{
    var response = _service.Process<List<Country>>(BackOfficeEndpoint.CountryEndpoint, "returnCountries");

    return Task.FromResult(response);
}
Run Code Online (Sandbox Code Playgroud)

我测试了上面的代码并且正在运行.但我不确定它是否正确用法async/await.请分享你的想法.

c# asp.net-mvc async-await asp.net-web-api

104
推荐指数
2
解决办法
15万
查看次数

同步使用漂亮的.net 4.5 HttpClient的最佳方法

我喜欢新的System.Net.Http.HttpClient类.它有一个很好的简单API,它不会抛出正常的错误.但它只是异步.

我需要代码(深入服务器内)

foo();
bar();
// compute stuff
var x = GetThingFromOtherServerViaHttp();
// compute more stuff
wiz(x);
Run Code Online (Sandbox Code Playgroud)

经典的顺序同步代码.我看到了几个类似的问题,但实际上从未真正说过"做这个".我在看

client.PostAsync.Wait()
Run Code Online (Sandbox Code Playgroud)

世界尖叫'不要这样做'.怎么样:

client.PostAsync.Result()
Run Code Online (Sandbox Code Playgroud)

这不只是伪装等待?

最后,我最终传入一个处理结果的lambda回调,然后唤醒显式等待EventWaitHandle的调用线程.很多管道.有没有更简单的东西或者我只是回到使用旧的http客户端

编辑:进一步阅读后,我怀疑这段代码与Wait和Result有相同的问题,它只是一个更长的死锁

编辑:我有MS PM最近向我确认有一个任务'可能需要> X ms(我忘了​​X)的任何API必须是异步',许多PM将此解释为'仅异步'(不清楚这是什么旨在).因此Document DB api只是异步.

c# task-parallel-library

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

同步使用HttpClient的“正确方法”是什么?

我在“正确的方法”周围使用了引号,因为我已经清楚地知道使用异步API的正确方法是简单地让异步行为在整个调用链中传播。这里不是一个选择。

我正在处理一个非常大而复杂的系统,该系统专门设计用于在循环中同步进行批处理。

我突然使用HttpClient的原因是因为在此之前,用于批处理的所有数据都是从SQL数据库中收集的,而现在我们将Web API调用添加到了混合中。

是的,我们正在同步执行循环中调用Web API。我知道。重写整个事情是异步的不是一个选择。这实际上是我们想要做的。(我们正在尽可能减少API调用的次数)

实际上,我确实尝试在调用链上传播异步行为,但是后来我发现自己有50个文件有很深的变化,仍然有数百个编译器错误需要解决,并失去了所有希望。我被打败了。

因此,回到问题所在,考虑到Microsoft的建议,从不使用WebRequest进行新开发,而改用HttpClient(仅提供异步API),我该怎么办?

这是我在做什么的伪代码...

foreach (var thingToProcess in thingsToProcess)
{
    thingToProcess.ProcessStuff(); // This makes an API call
}
Run Code Online (Sandbox Code Playgroud)

如何实现ProcessStuff()?

我的第一个实现看起来像这样

public void ProcessStuff()
{
    var apiResponse = myHttpClient // this is an instance of HttpClient
        .GetAsync(someUrl)
        .Result;

    // do some stuff with the apiResponse
}
Run Code Online (Sandbox Code Playgroud)

但是,我被告知,由于同步上下文而从ASP.NET之类的方法调用.Result时,以这种方式调用它可能导致死锁。

猜猜是什么,该批处理过程将从ASP.NET控制器开始。是的,再次,我知道,这很愚蠢。从ASP.NET运行时,它仅是“批处理”一项,而不是整个批处理,但是我离题了,它仍然从ASP.NET调用,因此我担心死锁。

那么解决这个问题的“正确方法”是什么?

c# asynchronous async-await

5
推荐指数
2
解决办法
3361
查看次数

httpclient异步/等待与否

我正在使用一个httpclient实例发送多个请求来休息web api以获取数据.这是我的代码的样子:

首先,我有一个控制层,用于调用数据的数据层.

public class ControlLayer
{
    protected DataLayer dal;

    //constructors here

    public int getInfo1(int param)
    {
      int ret = this.dal.getInfo1(param);
      return ret;
    }

    public int getInfo2(int param)
    {
      int ret = this.dal.getInfo2(param);
      return ret;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我有调用webAPI的dataLayer,它看起来像这样.这里为了简单起见,我直接使用.result.

public class DataLayer
{
    HttpClient client = new HttpClient();
    string url = "";

    public int getInfo1(int param1)
    {
      int ret=0;
      HttpResponseMessage response = client.GetAsync(url).Result;
      //.... do some work, get the value for ret

      return ret;
    }

    public int getInfo2(int param1)
    {
      int …
Run Code Online (Sandbox Code Playgroud)

c# async-await dotnet-httpclient

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

为什么在 HttpWebRequest 上使用 HttpClient 进行同步请求

在我的场景中,我必须将数据从一个 Web 应用程序发送到一个有效的数据存储 webapi。请求必须是同步的,Exception如果出现问题,我绝对希望抛出,因为这意味着应用程序的关键部分不可用。

这是现有问题的衍生,但不是重复;为什么使用 HttpClient 进行同步连接

然而一遍又一遍,包括在我上面看到的文章中,我看到一致的建议使用HttpClient,即使在同步场景中也是如此。我看到的最好的原因是上面 SO 帖子中接受的答案,但它基本上归结为;

使用它是因为“闪亮”。

对于我的场景,我不喜欢这是一个可接受的答案。我更愿意为手头的任务使用正确的对象,这似乎是较旧的HttpWebRequest. 甚至 Ben Watson 的优秀资源“编写高性能 .NET 代码”也说明了以下内容;

另一个例子是System.Net.HttpWebRequest类,如果它收到来自服务器的非 200 响应,它将抛出异常。幸运的是,这种奇怪的行为System.Net.Http.HttpClient在 .NET 4.5的类中得到了纠正

但在我的情况,我其实希望这样的行为。虽然 有很多很好的用例HttpClient,但谁能提供一个不在HttpWebRequest我的场景中使用的好理由?我是否使用了正确的对象?更重要的是,为什么

c# httpclient httpwebrequest

2
推荐指数
1
解决办法
2284
查看次数