这是一个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”完成的吗?
答案 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();
}