等到完成(网络服务)

时间:2013-04-26 06:25:36

标签: c# multithreading web-services windows-phone-7

我正在研究web services ...
下面是我写给web service

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

CheckIfUserExist方法调用该Web服务并返回输出值(UserID)---&gt;

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&amp;它总是出错......

我也试过了manualResetEvent,但它阻止了我的UI Thread ......所以没有效果

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

2 个答案:

答案 0 :(得分: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 <---
         }

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

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.Invoke问题,请看:Can't use dispatcher on WP7

答案 1 :(得分:1)

是的我建议您使用“等待” - “异步”技术。为了确保在继续代码之前完成该功能。

以下是您的代码应该是什么样的:

此处有更多信息 - &gt; 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;
     }
 }