范围如何为Task.Factory.Startnew工作?

时间:2014-07-07 19:02:45

标签: c# wcf silverlight asynchronous scope

我有一个Silverlight网站,它调用WCF服务,以便它可以进行一些服务器端加载。 WCF调用是异步的,因为它是Silverlight就绪的,所以在它完成时,我正在从CompletedEventArgs读取数据以加载类。但是,我不确定范围如何运作。 data在新任务的范围内是否与外部相同?它似乎永远不会被设置为true。我知道该服务正在运行,因为异步调用正在发生,但是我无法调试完成事件触发因为我无法将调试器附加到“ASP.net-hosted-Silverlight”(有没有办法)解决这个问题?我希望能够在托管.aspx时调试Silverlight ...)。我用this link.来解决这个问题我正在测试我的项目,但是我我仍然很好奇这个范围如何运作。

感谢您的帮助!

编辑:我意识到这可能是构建此功能的一种可怕方式,我正在寻找替代建议:)

// Objects constructor calls async WCF task, upon completion of which (grammar?)
//    sets IsComplete to true
Foo data = new Foo(param);

Task waitForComplete = Task.Factory.StartNew(() =>
    {
        while (!data.IsComplete)
        {
            // Wait 1 second, then poll again
            System.Threading.Thread.Sleep(1000 * 1);
        }
    });

Task.WaitAll(new Task[] { waitForComplete });

// Now that the task has completed, we can access its data
bar.AddRange(data.GetFoo());

1 个答案:

答案 0 :(得分:1)

通常,您通过调用Task.WaitAll来阻止主线程。 Foo类可能正在尝试将回调发布到该线程上,这将永远不会成功。这可以解释为什么你从未真正“完成”任务。

通常,更好的方法是尽可能避免轮询(例如,一个选项是将Task / Task<T>暴露给调用者,因此您可以附加一个继续那里)。但是,如果您无法更改Foo的实现,则可以将其切换为处理将数据设置为延续而不是阻止:

// Don't block
// Task.WaitAll(new Task[] { waitForComplete });

// Instead, schedule a continuation that runs when the task is done...
waitForComplete.ContinueWith(t =>
{
    // Now that the task has completed, we can access its data
    bar.AddRange(data.GetFoo());
}, TaskScheduler.FromCurrentSynchronizationContext());