0

我正在研究web services...
下面是我编写的调用方法web service

 long UserID = CheckIfUserExist(temp);       
    if (UserID == -1)
           // WRONG RESULT <---
    else
          // RIGHT RESULT <---

CheckIfUserExist调用该 Web 服务并返回输出值的方法 ( UserID)--->

public static long CheckIfUserExist()
{                
     long UserID = -1;
     client.GetAsync("me");  
     client.GetCompleted += (o, e) =>
     {
         // some code
         if (Convert.ToInt64(eargs.Result) == 0)
         {
               UserID = Convert.ToInt64(eargs.Result);
         }
         return UserID;
     }
 }

但是在CheckIfUserExist执行 GetCompleted 之前返回输出值及其总是出错的结果......

我也试过manualResetEvent了,但它挡住了我的UI Thread……所以没用

所以有人有任何想法来解决这个问题吗?

4

2 回答 2

3

Async Await 关键字是解决您的情况的一种方法。但是,您的实际问题是您不了解GetAsync呼叫的工作原理。当你说:

public static long CheckIfUserExist()
{                
     long UserID = -1;
     client.GetAsync("me");  
     client.GetCompleted += (o, e) =>
     {
         // some code
         if (Convert.ToInt64(eargs.Result) == 0)
         {
               UserID = Convert.ToInt64(eargs.Result);
         }
         return UserID;
     }
 }

它相当于:

    public static long CheckIfUserExist()
    {                
     long UserID = -1;
     client.GetAsync("me");  
     client.GetCompleted += MyEventHandler;

    }

    void MyEventHandler(object sender, SomeEventArgs e)
    {
         // some code
         if (Convert.ToInt64(eargs.Result) == 0)
         {
           UserID = Convert.ToInt64(eargs.Result);
         }
         return UserID; // <-- WHAT IS POINT OF RETURNING UserID FROM HERE?? 
                        // method maybe running on some other thread asynchronously to UI thread
    }

您有两种可能性: 如果您的client对象的GetCompleted事件发生在 UI 线程上,您可以这样做:

 client.GetCompleted += (o, e) =>
         {
             // some code
             if (Convert.ToInt64(eargs.Result) == 0)
             {
               UserID = Convert.ToInt64(eargs.Result);
             }
             // your logic here
             if (UserID == -1)
                  // WRONG RESULT <---
             else
                  // RIGHT RESULT <---
         }

如果GetCompletedUI 线程上没有发生事件:

client.GetCompleted += (o, e) =>
             {
                 // some code
                 if (Convert.ToInt64(eargs.Result) == 0)
                 {
                   UserID = Convert.ToInt64(eargs.Result);
                 }
                 // let UI thread know we've got the result
                 Dispatcher.Invoke( (Action)(() => { NotifyUIThread(UserID) } ));
             }
...

void NotifyUIThread(long UserId) //This runs on UI thread
{
    if (UserID == -1)
       // WRONG RESULT <---
    else
       // RIGHT RESULT <---

}

另外,请注意在您致电之前订阅事件GetAsync

client.GetCompleted += (o, e) => { ... } //subscribe first
client.GetAsync("me");  // call GetAsync later

如果在 WP7 上 - 你可能会遇到问题Dispatcher.InvokeCan't use dispatcher on WP7

于 2013-04-26T22:11:50.030 回答
1

是的,我建议你使用“await”-“async”技术。在继续代码之前确保函数完全完成。

这是您的代码应如下所示:

更多信息在这里-> http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

public async void updateUser()
{
   long UserID = await CheckIfUserExist(temp);       
   if (UserID == -1)
       // WRONG RESULT <---
   else
      // RIGHT RESULT <---
}

public async Task<long> CheckIfUserExist()
{                
     long UserID = -1;
     await client.GetAsync("me");  
     client.GetCompleted += (o, e) =>
     {
         // some code
         if (Convert.ToInt64(eargs.Result) == 0)
         {
               UserID = Convert.ToInt64(eargs.Result);
         }
         return UserID;
     }
 }
于 2013-04-26T09:12:34.010 回答