异步替代品

时间:2012-09-07 10:35:07

标签: c# windows-phone-7 async-ctp onedrive

我正在尝试在我的应用中实现此代码,以便将数据备份到skydrive http://netitude.bc3tech.net/2012/07/11/skydrive-backup-of-your-mobile-applets-get-some-common-ground/

但是我怎么也无法安装Async CTP(我测试了2-3天但async ctp没有安装好......我已经尝试了解决方案,但问题仍然存在)。有可能做同样但不使用异步?如何等待完成任务继续?

使用这些工具" Windows Phone SDK 7.1和7.1.1更新":https://dev.windowsphone.com/en-us/downloadsdk

(...)

var rootFolders = JObject.Parse((await client.GetAsyncTask("/me/skydrive/files?filter=folders,albums")).RawResult);
var progDataFolder = rootFolders["data"].FirstOrDefault(f => f.Value<string>("name").Equals("programdata", StringComparison.OrdinalIgnoreCase));
string progDataFolderId;
if (progDataFolder == null)
{
    var result = await client.PostAsyncTask("me/skydrive/",
        new Dictionary<string, object>() { { "name", "ProgramData" } });**

    progDataFolderId = JObject.Parse(result.RawResult).Value<string>("folder_id");
}
else
{
    progDataFolderId = progDataFolder.Value<string>("id");
}

var windowsPhoneFolder = JObject.Parse((await client.GetAsyncTask(string.Concat("/", progDataFolderId, "/files?filter=folders,albums"))).RawResult)["data"]
    .FirstOrDefault(f => f.Value<string>("name").Equals("windows phone", StringComparison.OrdinalIgnoreCase));
string windowsPhoneFolderId;
if (windowsPhoneFolder == null)
{
    var result = await client.PostAsyncTask(string.Concat("/", progDataFolderId),
        new Dictionary<string, object>() { { "name", "Windows Phone" } });**

    windowsPhoneFolderId = JObject.Parse(result.RawResult).Value<string>("id");
}
else
{
    windowsPhoneFolderId = windowsPhoneFolder.Value<string>("id");
}

(...)

替代方法。例如:

var result = await client.PostAsyncTask("me/skydrive/",
            new Dictionary<string, object>() { { "name", "ProgramData" } });

2 个答案:

答案 0 :(得分:0)

如果你有Task,你可以使用所谓的“延续传递方式”。基本上,在您使用await的任何地方,您都会调用Task.ContinueWith并传递方法的其余部分。循环更复杂,但也可以继续处理。

请注意,如果未正确安装Async CTP,GetAsyncTask可能无法正常运行。因此,在您的情况下,我建议您使用LiveConnectClient类已经支持的Event-based Asynchronous Pattern (EAP):例如,订阅GetCompleted事件,然后致电GetAsync。有关示例,请参阅this post

答案 1 :(得分:0)

假设相同的代码不使用仅在新版本的框架中可用的任何方法,您可以简单地使用TPL方法来重现await所做的事情。 await使用执行await的代码的同步上下文运行continuation。因此,要复制,您需要使用ContinueWith的重载,该重载接受TaskScheduler并从当前上下文传入TaskScheduler。例如:

TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
client.PostAsyncTask("me/skydrive/", new Dictionary<string, object>() {{"name", "ProgramData"}})
    .ContinueWith(t =>
                    {
                    progDataFolderId= JObject.Parse(result.RawResult).Value<string>("folder_id");
                    });

现在,这是将一个await转换为带有任务调度程序的TPL方法的简单部分。编译器实际上在做的是在async方法中创建状态机(包含所有await代码的方法)。该状态机已将原始代码分解为块并跟踪progDataFolder == null之类的各种内容,因为在您的情况下,可以通过两种不同的方式调用第一个else之后的代码。一个是异步的 - 如果progDataFolder为null,则异步调用else之后的代码,如果progDataFolder不为null,则从progDataFolderId实例设置progDataFolder并且在else之后的代码同步。因此,您必须使用TPL方法正确模式。即,当progDataFolder不是null时,您不会在延续时间之后运行代码。