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

时间:2011-03-26 11:27:15

标签: c# windows-phone-7 c#-4.0 asynchronous

这是一个Windows Phone7项目。 我的代码中有一些异步调用,最终填充了一个全局的List。但我的问题是,我如何知道何时完成异步作业,以便我可以继续使用代码? 编辑我更新了代码:

 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”完成的吗?

3 个答案:

答案 0 :(得分:1)

我选择了以下代码,它正在为我的程序工作。谢谢你的帮助!

 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();
                }                    
            });

这样,当Flickr调用结束时,我调用方法ShowPhotos()

答案 1 :(得分:0)

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

您的方法签名可能如下所示:例如:

public IAsyncResult BeginOperation(AsyncCallback callback)

public EndOperation(IAsyncResult result)

来自MSDN

  

IAsyncResult接口是   由包含的类实现   可以操作的方法   异步。它是返回类型   启动的方法   异步操作,如   IsolatedStorageFileStream.BeginRead,   并传递给结束的方法   异步操作,例如   IsolatedStorageFileStream.EndRead。一个   IAsyncResult也传递给了   由a调用的方法   当一个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());
        }
    }
}

答案 2 :(得分:0)

在最简单的情况下,您可以提供回调,或者稍加努力,创建一个在工作完成时引发的事件。这是回调代码:

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();
}