相关疑难解决方法(0)

await vs Task.Wait - 死锁?

我不太明白之间的差别Task.Waitawait.

我在ASP.NET WebAPI服务中有类似于以下函数:

public class TestController : ApiController
{
    public static async Task<string> Foo()
    {
        await Task.Delay(1).ConfigureAwait(false);
        return "";
    }

    public async static Task<string> Bar()
    {
        return await Foo();
    }

    public async static Task<string> Ros()
    {
        return await Bar();
    }

    // GET api/test
    public IEnumerable<string> Get()
    {
        Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());

        return new string[] { "value1", "value2" }; // This will never execute
    }
}
Run Code Online (Sandbox Code Playgroud)

哪里Get会僵局.

什么可能导致这个?当我使用阻塞等待而不是await Task.Delay?时,为什么这不会导致问题?

c# deadlock task-parallel-library async-await

169
推荐指数
3
解决办法
13万
查看次数

不在TPL Task对象上调用Dispose()是否可以接受?

我想触发一个在后台线程上运行的任务.我不想等待任务完成.

在.net 3.5中,我会这样做:

ThreadPool.QueueUserWorkItem(d => { DoSomething(); });
Run Code Online (Sandbox Code Playgroud)

在.net 4中,TPL是建议的方式.我见过的常见模式是:

Task.Factory.StartNew(() => { DoSomething(); });
Run Code Online (Sandbox Code Playgroud)

但是,该StartNew()方法返回一个Task实现的对象IDisposable.推荐这种模式的人似乎忽视了这一点.有关该Task.Dispose()方法的MSDN文档说:

"在释放对任务的最后一个引用之前,始终调用Dispose."

你不能在任务完成之前调用dispose,所以让主线程等待并调用dispose会首先打破后台线程上的操作.似乎也没有任何已完成/已完成的事件可用于清理.

Task类上的MSDN页面没有对此进行评论,并且"Pro C#2010 ..."一书推荐了相同的模式,并且没有对任务处理做出评论.

我知道如果我离开它,终结者最终会抓住它,但当我做了大量的火灾并且忘记了这样的任务并且终结者线程被淹没时,它会回来咬我吗?

所以我的问题是:

  • 是否可以接受不叫Dispose()Task在这种情况下类?如果是这样,为什么会有风险/后果?
  • 有没有讨论这个的文件?
  • 或者是否有适当的方法来处理Task我错过的物体?
  • 或者是否有其他方法可以使用TPL执行解雇和忘记任务?

.net c# multithreading dispose task-parallel-library

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

为什么我懒得使用Task.ConfigureAwait(continueOnCapturedContext:false);

请考虑以下Windows窗体代码:

private async void UpdateUIControlClicked(object sender, EventArgs e)
    {
        this.txtUIControl.Text = "I will be updated after 2nd await - i hope!";
        await Task.Delay(5000).ConfigureAwait(continueOnCapturedContext: false);
        this.txtUIControl.Text = "I am updated now.";
    }
Run Code Online (Sandbox Code Playgroud)

这里异常是在第3行引发的,因为在等待代码在非UI线程上执行之后.ConfigureAwait(false)有用吗?

c# synchronizationcontext async-await

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

在WebApi或MVC控制器中使用ConfigureAwait(false)有任何危险吗?

说我有两个场景:

1)WebApi控制器

    [System.Web.Http.HttpPost]
    [System.Web.Http.AllowAnonymous]
    [Route("api/registerMobile")]
    public async Task<HttpResponseMessage> RegisterMobile(RegisterModel model)
    {
        var registerResponse = await AuthUtilities.RegisterUserAsync(model, _userService, User);
        if (registerResponse.Success) {
            var response = await _userService.GetAuthViewModelAsync(model.Username, User);
            return Request.CreateResponse(HttpStatusCode.OK, new ApiResponseDto() { Success = true, Data = response });
        }
        else {
            return Request.CreateResponse(HttpStatusCode.OK, registerResponse);
        }

    }
Run Code Online (Sandbox Code Playgroud)

2)MVC控制器

    [Route("public")]
    public async Task<ActionResult> Public()
    {
        if (User.Identity.IsAuthenticated)
        {
            var model = await _userService.GetAuthViewModelAsync(User.Identity.Name);
            return View("~/Views/Home/Index.cshtml", model);
        }
        else
        {
            var model = await _userService.GetAuthViewModelAsync(null);
            return View("~/Views/Home/Index.cshtml", model);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我一直在阅读我应该使用的时间ConfigureAwait …

.net c# asp.net-mvc asynchronous asp.net-web-api

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

我们应该在调用异步回调的库中使用ConfigureAwait(false)吗?

ConfigureAwait(false)在C#中使用await/async 时,有很多指南可供使用.

似乎一般的建议是ConfigureAwait(false)在库代码中使用,因为它很少依赖于同步上下文.

但是,假设我们正在编写一些非常通用的实用程序代码,它将函数作为输入.一个简单的例子可能是以下(不完整的)功能组合器,以简化基于任务的简单操作:

地图:

public static async Task<TResult> Map<T, TResult>(this Task<T> task, Func<T, TResult> mapping)
{
    return mapping(await task);
}
Run Code Online (Sandbox Code Playgroud)

FlatMap:

public static async Task<TResult> FlatMap<T, TResult>(this Task<T> task, Func<T, Task<TResult>> mapping)
{
    return await mapping(await task);
}
Run Code Online (Sandbox Code Playgroud)

问题是,我们应该ConfigureAwait(false)在这种情况下使用吗?我不确定上下文捕获是如何工作的.关闭.

一方面,如果组合器以功能方式使用,则不需要同步上下文.另一方面,人们可能会滥用API,并在提供的函数中执行依赖于上下文的内容.

一种选择是为每个场景(Map和/ MapWithContextCapture或某些东西)设置单独的方法,但感觉很难看.

另一种选择可能是将map/flatmap选项添加到a中ConfiguredTaskAwaitable<T>,但是由于等待不必实现接口,这会导致大量冗余代码,在我看来更糟糕.

是否有一种将责任转交给调用者的好方法,这样实现的库就不需要对提供的映射函数中是否需要上下文做出任何假设?

或者仅仅是一个事实,异步方法组成得不是很好,没有各种假设?

编辑

只是为了澄清一些事情:

  1. 问题确实存在.当您在效用函数内执行"回调"时,添加ConfigureAwait(false)将导致空同步.上下文.
  2. 主要问题是我们应该如何处理这种情况.我们是否应该忽略某人可能想要使用同步的事实.上下文,还是有一个很好的方法将责任转移到调用者,除了添加一些重载,标志等?

正如一些答案所提到的那样,可以在方法中添加一个bool-flag,但正如我所看到的,这也不是太漂亮,因为它必须一直传播到API中(因为它有)更多"实用"功能,取决于上面显示的功能.

c# task synchronizationcontext task-parallel-library async-await

35
推荐指数
3
解决办法
2682
查看次数

等待与异步方法中的Task.Result

执行以下操作之间有什么区别:

async Task<T> method(){
    var r = await dynamodb.GetItemAsync(...)
    return r.Item;
}
Run Code Online (Sandbox Code Playgroud)

VS

async Task<T> method(){
    var task = dynamodb.GetItemAsync(...)
    return task.Result.Item;
}
Run Code Online (Sandbox Code Playgroud)

在我的情况下,由于某种原因,只有第二个工作.第一个似乎永远不会结束.

c# asynchronous task async-await amazon-dynamodb

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

使http客户端同步:等待响应

我有一些文件要上传,一些文件失败,因为帖子是异步的而不是同步的..

我正在尝试将此调用作为同步调用..

我想等待回应.

如何将此调用设为同步?

static async Task<JObect> Upload(string key, string url, string 
                                 sourceFile, string targetFormat)
{ 
    using (HttpClientHandler handler = new HttpClientHandler { 
                                           Credentials = new NetworkCredential(key, "") 
                                       })
    using (HttpClient client = new HttpClient(handler))
    {
         var request = new MultipartFormDataContent();
         request.Add(new StringContent(targetFormat), "target_format");
         request.Add(new StreamContent(File.OpenRead(sourceFile)),
                                       "source_file",
                                        new FileInfo(sourceFile).Name);

        using (HttpResponseMessage response = await client.PostAsync(url,
                                                           request).ConfigureAwait(false))

        using (HttpContent content = response.Content)
        {
            string data = await content.ReadAsStringAsync().ConfigureAwait(false);
            return JsonObject.Parse(data);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏!

c# httpresponse dotnet-httpclient

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

结合应用程序域远程处理和任务时的死锁

我的应用程序需要将插件加载到单独的应用程序域中,然后异步执行其中的一些代码.我编写了一些代码来包装可Task编组类型:

static class RemoteTask
{
    public static async Task<T> ClientComplete<T>(RemoteTask<T> remoteTask,
                                                  CancellationToken cancellationToken)
    {
        T result;

        using (cancellationToken.Register(remoteTask.Cancel))
        {
            RemoteTaskCompletionSource<T> tcs = new RemoteTaskCompletionSource<T>();
            remoteTask.Complete(tcs);
            result = await tcs.Task;
        }

        await Task.Yield(); // HACK!!

        return result;
    }

    public static RemoteTask<T> ServerStart<T>(Func<CancellationToken, Task<T>> func)
    {
        return new RemoteTask<T>(func);
    }
}

class RemoteTask<T> : MarshalByRefObject
{
    readonly CancellationTokenSource cts = new CancellationTokenSource();
    readonly Task<T> task;

    internal RemoteTask(Func<CancellationToken, Task<T>> starter)
    {
        this.task = starter(cts.Token);
    }

    internal void Complete(RemoteTaskCompletionSource<T> tcs)
    {
        task.ContinueWith(t …
Run Code Online (Sandbox Code Playgroud)

c# deadlock appdomain task-parallel-library

15
推荐指数
1
解决办法
2597
查看次数

避免使用Async重复代码

如何避免为异步和非异步方法编写相同的代码两次.我目前正在使用ASP.NET,因此我目前正在使用请求线程,并且我很快就知道他在代码下面(应该显示我的意图),这肯定是错误的做法.

应用程序死锁,因为await关键字试图返回.Result阻塞的同一线程.

我这样做的全部原因是避免两次编写相同的"FindAll"代码.

public IEnumerable<Resource> FindAll()
{
   return FindAllAsync().Result;

}

public async Task<IEnumerable<Resource>> FindAllAsync()
{
   return await Context.Resources.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)

那你怎么解决这个问题呢?

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

13
推荐指数
1
解决办法
2263
查看次数

Service Fabric可靠队列长操作

我正在尝试了解服务结构的一些最佳实践.

如果我有一个由Web服务或其他机制添加的队列和后端任务来处理该队列,那么在后台处理长时间运行的操作的最佳方法是什么.

  1. 在一个事务,进程中使用TryPeekAsync,然后如果成功使用TryDequeueAsync最终出列.
  2. 使用TryDequeueAsync删除项目,将其放入字典中,然后在完成后从字典中删除.在启动服务时,检查字典以查找队列之前的待处理状态.

两种方式都有点不对劲,但如果有更好的方法我就无法解决.

azure-service-fabric

9
推荐指数
1
解决办法
4678
查看次数