【问题标题】:Is it safe to call the ContinueWith method on a TaskCompletionSource.Task (that has had it's .SetResult called)?在 TaskCompletionSource.Task 上调用 ContinueWith 方法是否安全(已经调用了 .SetResult)?
【发布时间】:2011-09-15 15:41:39
【问题描述】:

如果TaskCompletionSource.SetResult(...) 已经被调用,那么在TaskCompletionSource.Task 上使用ContinueWith(...) 方法是否安全?

此基本代码有望帮助解决问题:

// this was written inside the question box, please excuse any silly errors and lack of error checking (I'm not near VS right now)...

private WebClient _webClient = new WebClient();

public Task<string> GetExamplePage() {

    var tcs = new TaskCompletionSource<string>();

    web.DownloadStringCompleted += (s, ea) => tcs.SetResult(ea.Result);

    web.DownloadStringAsync(new URI(@"http://www.example.com/example.html"));

    return tcs.task;
}

public void ProcessExamplePage() {
    
    var task = GetExamplePage();

    Thread.Sleep(1000);

    task.ContinueWith(t => Console.WriteLine(t.Result)); // *line in question*
}

如果WebClient.DownloadStringCompleted 事件在task.ContinueWith 设置之前已经触发,Console.WriteLine(...) 会执行吗?

MSDN 有话要说 (Task.ContinueWith):

Task.ContinueWith 方法

返回的任务将不会被安排执行,直到 当前任务已完成,是否因运行而完成 成功完成,由于未处理的异常而出错,或 由于被取消而提前退出。

不幸的是,没有提到如果调用此方法并且任务已经完成会发生什么。

提前感谢您提供的任何信息! :)

【问题讨论】:

    标签: c# .net asynchronous task-parallel-library


    【解决方案1】:

    是的,这应该没问题,ContinueWith 检查上一个任务是否完成,如果完成,它将立即排队继续。

    【讨论】:

    • 这会启动一个新的异步操作还是同步继续?由于TaskCompletionSource 没有启动异步操作。
    • 不错。参考有关这方面的文档会很棒。
    • @annemartijn 这取决于原始任务(或延续)是否指定TaskCreationOptions​.​RunContinuationsAsynchronously(或TaskContinuationOptions​.​Run​Continuations​Asynchronously)​--​这些仅适用于它们的延续​- -​和/或延续是否指定TaskContinuationOptions​.​ExecuteSynchronously(这适用于延续本身)。
    【解决方案2】:

    如果指定任务在调用 ContinueWith 时已经完成,则同步延续将在调用 ContinueWith 的线程上运行。 https://msdn.microsoft.com/en-us/library/dd321576(v=vs.110).aspx

    【讨论】:

    • 错了。此文本是示例,通过指定 TaskContinuationOptions.ExecuteSynchronously
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多