2015-01-08 177 views
0

所以我对Windows手机和C#有点新,所以我知道我可能是错误的如何设置,所以也许有人可以指出我在正确的方向。在移动应用程序中,我们需要能够调用特定的服务来生成会话guid,然后再继续调用其他方法,所以从我迄今阅读的内容来看,似乎我需要将该调用放入任务,然后我可以使用await方法来防止下一个项目被调用,但是我无法弄清楚的是在任务内如何调用Web服务方法并在任务完成之前获取结果。以下是我迄今为止所做的,我尝试了其他来自各种渠道的其他一些不起作用的东西,因此我决定将它还原为第一次尝试,然后在此处发布以获得帮助。等待异步Web服务调用完成内部任务

public static async Task<Guid> GetAMSessionGUID() 
{ 
    Debug.WriteLine("setting up client"); 
    AMClient client = new AMClient(); 
    Guid session = new Guid(); 
    client.GetSessionCompleted += delegate(object sender, GetSessionCompletedEventArgs e) 
    { 
     session = e.Result.session_ID; 
     Debug.WriteLine("session completed " + session); 
    }; 
    client.GetSessionAsync(); 
    return session; 
} 
+0

我编辑了自己的冠军。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 –

+0

对不起约翰,当我在Google上寻找答案时,我得到了各种Java和F#答案,并且因为我需要C#,所以我认为我应该在开始时说清楚。我将确保避免在标题中使用标签。 –

回答

2

什么是AMClient类型? GetSessionAsync()方法是如何声明的?

我猜测,从你的问题的性质,该方法声明如下:

public void GetSessionAsync() 

而且该“异步”指的是,该方法立即返回,与GetSessionCompleted事件在操作实际完成时引发。如果是这样,那么您可以使用TaskCompletionSource<T>类来帮助您实现适合您的方法的友好包装器async/await。例如:

public static Task<Guid> GetAMSessionGUIDAsync() 
{ 
    Debug.WriteLine("setting up client"); 
    AMClient client = new AMClient(); 
    TaskCompletionSource<Guid> completionSource = new TaskCompletionSource<Guid>(); 

    client.GetSessionCompleted += (sender, e) => 
    { 
     Debug.WriteLine("session completed " + session); 
     completionSource.SetResult(e.Result.session_ID); 
    }; 
    client.GetSessionAsync(); 

    return completionSource.Task; 
} 

的方法本身并不需要为async,因为它实际上没有等待任何东西本身。请注意,我还将事件订阅更改为更简洁的lambda语法,并将该方法重命名为名称以Async这个词,这个方法的.NET约定结束。

TaskCompletionSource<T>对象有两个相关的事情:它给你一个地方来存储操作的结果;它会给你Task<T>代表操作,并可以像其他Task<T>一样等待。

因此,实现为上述方法,你可以使用它是这样的:

async Task DoSomeStuff() 
{ 
    // do initial stuff 

    Guid sessionGuid = await GetAMSessionGUIDAsync(); 

    // do some other stuff 
} 
+0

谢谢Perter,对不起,我不太清楚我的初步问题。AMClient是一个SOAP WebService,我添加到项目使用添加服务选项为Web服务创建所有类,我将立即尝试您的方法,看看它是否适用于我所需要的。 –

0

你应该await调用异步方法(通常是那些带有Async结尾)。

所以在方法,你提供的,你应该await client.GetSessionAsync();

那么你应该等待你自己的方法的调用(地道,你应该异步后缀添加到其名称也是如此)。

+0

只有当'GetSessionAsync()'本身等待时,它才有效,即返回一个'Task'。你有没有证实这确实是这种情况? –

+0

不!对我来说,手腕上有一丝瑕疵。如果你不能等待异步结束方法(或者ToTask()),那么也许是另一种方式)如果你不能等待它,那么你的TaskCompletionSource方法当然是最好的方法! – rdavisau

+0

无论好坏,“......”异步命名约定早于TPL,当然也有'async' /'await'。所以应该准备好使用这个惯例的很多旧的旧版API,即使它们不适合新的'async' /'await'模式。人们希望今天新发布的API只能将该惯例用于真正的可等待的API,但即使这样也不能保证,并且考虑到较早的先例,甚至可以说是“很好”(因为发布了一个不兼容的新异步API 'async' /'await'可以被认为是好的,恕我直言“不是那么多:) –