如何知道我的异步功能何时完成? (windows phone7 dev)

问题描述:

这是一个Windows Phone7项目。 我在我的代码中有几个异步调用,最后,填充一个全局的List。但是我的问题是,我怎么知道的异步作业完成了,这样我就可以在代码中继续了? 编辑我更新的代码:如何知道我的异步功能何时完成? (windows phone7 dev)

private void GetFlickrPhotos(Action finishedCallback) 
    { 
     Action<FlickrResult<PhotoCollection>> getPhotoCollectionCallback; 
     getPhotoCollectionCallback = GetPhotoCollection; 
     flickr.InterestingnessGetListAsync(getPhotoCollectionCallback); 
     finishedCallback(); 
    } 

    private void GetPhotoCollection(FlickrResult<PhotoCollection> photoColl) 
    { 
     PhotoCollection photoCollection = (PhotoCollection)photoColl.Result; 

     foreach (Photo photo in photoCollection) 
     { 
      flickrPhotoUrls.Add(photo.MediumUrl); 
     }   
    } 

    private void Grid_Loaded(object sender, RoutedEventArgs e) 
    { 
     GetFlickrPhotos(() => 
     { 
      int test = flickrPhotoUrls.Count; 
     });    
    } 

异步调用.NET框架4.使用Action<T>它仍然不会等待异步调用完成。是因为异步调用是从“GetFlickrPhotos”完成的吗?

我去了下面的代码,它为我的程序工作。感谢您的帮助!

app.Flickr.PhotosSearchAsync(options, flickrResult => 
      { 
       if (flickrResult.HasError) 
       {           
        ShowErrorImage(); 
       } 
       else 
       {       
        flickrPhotoUrls.Clear(); 
        flickrImages.Clear(); 
        foreach (var item in flickrResult.Result) 
        { 
         FlickrImage image = new FlickrImage(); 
         image.ImageOwner = item.OwnerName; 
         image.DateTaken = item.DateTaken; 
         if (item.Title == string.Empty) 
         { 
          image.ImageTitle = "Untitled"; 
         } 
         else 
         { 
          image.ImageTitle = item.Title; 
         } 
         image.SmallUrl = item.SmallUrl; 
         image.MediumUrl = item.MediumUrl; 
         image.Description = item.Description; 
         image.Latitude = item.Latitude; 
         image.Longitude = item.Longitude; 
         if (item.DoesLargeExist == true) 
         { 
          image.LargeUrl = item.LargeUrl; 
         } 

         flickrImages.Add(image); 
        } 
        ShowPhotos(); 
       }      
      }); 

这样,我调用该方法ShowPhotos()当Flickr的通话结束。

调查IAsyncResult - 这里有很多与这个特定模式相关的资源,但基本上这将允许您维护一个对象的实例,它的作用就是让您确定操作的当前状态 - 甚至专门拨打End方法来中断操作。

你的方法签名可能会是这个样子,比如:

public IAsyncResult BeginOperation(AsyncCallback callback) 

public EndOperation(IAsyncResult result) 

MSDN

IAsyncResult接口是 含有 方法,可以异步操作 类实现的。它是该启动 异步操作的方法,如 IsolatedStorageFileStream.BeginRead, 返回类型 并传递给结束 异步操作的方法,如 IsolatedStorageFileStream.EndRead。一个 IAsyncResult也传递给 方法,当 异步操作完成时,由 AsyncCallback委托调用该方法。

支持用于异步 操作 IAsyncResult接口存储状态 信息,并且提供了 同步对象,以允许 操作完成时发出信号 线程的对象。

编辑:

行,除非我失去了一些东西,然后一个简单的事件通知可能是所有你所需要的 - 考虑一类下面介绍以下用法:

var flickrOperation = new FlickrOperation(); 
flickrOperation.FlickrPhotoURLsLoaded += 
    delegate(object sender, EventArgs e) 
    { 
     var photoCount = flickrOperation.FlickrPhotoURLs.Count; 
    }; 
flickrOperation.BeginGetFlickrPhotoURLs(); 

现在让我们定义这个类,虽然是原始的,只是在这种情况下达到目的的一种手段。请注意,特别是声明的使用FlickrPhotoURLsLoaded - 这是它在操作完成燃煤(如回调加载的URL完成规定)事件:

class FlickrOperation 
{ 
    //the result: 
    //ultimately, hide this and expose a read only collection or something 
    public List<string> FlickrPhotoURLs = new List<string>(); 
    //the event: 
    //occurs when all returns photo URLs have been loaded 
    public event EventHandler FlickrPhotoURLsLoaded; 

    public void BeginGetFlickrPhotoURLs() 
    { 
     //perform the flickr call... 
     var getPhotoCollectionCallback = GetFlickrPhotoURLsCallback; 
     flickr.InterestingnessGetListAsync(getPhotoCollectionCallback); 
    } 

    private void GetFlickrPhotoURLsCallback(FlickrResult<PhotoCollection> result) 
    { 
     //perform the url collection from flickr result... 
     FlickrPhotoURLs.Clear(); 
     var photoCollection = (PhotoCollection)result.Result; 
     foreach (Photo photo in photoCollection) 
     { 
      flickrPhotoUrls.Add(photo.MediumUrl); 
     } 
     //check to see if event has any subscribers... 
     if (FlickrPhotoURLsLoaded != null) 
     { 
      //invoke any handlers delegated... 
      FlickrPhotoURLsLoaded(this, new EventArgs()); 
     } 
    } 
} 
+0

这可能与我发布的更新代码有关吗? – 2011-03-26 11:54:43

+0

谢谢,但仍然,我得到我的URL列表填充的唯一方法是通过在调用代码上设置断点:FlickrPhotoURLsLoaded(this,new EventArgs());如果我不在这里设置断点,代码只是进入下一行。是否有可能使代码等待调用完成,然后继续? – 2011-03-26 18:05:17

在最简单的情况下,你可以提供一个回调,或者多花些功夫,创建一个在工作完成时引发的事件。这里是一个回调代码:

private void Grid_Loaded(object sender, RoutedEventArgs e) 
{ 
    DoAsyncWork(()=>{ 
     //continue here 
    }); 

} 

private void DoAsyncWork(Action finishedCallback) 
{ 
    //Doing some async work, and in the end of the last async call, 
    //a global List<string> myList is filled 
    //at this point call: 
    //finishedCallback(); 
} 
+0

我更新了代码,但正如您所看到的,异步调用是在下一个函数中完成的。我如何用我更新的代码来做到这一点?我完全陌生,这:) – 2011-03-26 11:53:46