简体   繁体   English

Silverlight-等待异步任务完成

[英]Silverlight - Wait for async task to complete

Here is what i have done so far: 到目前为止,这是我所做的:

All of the below code will get looped through and different URL's will be sent each time. 以下所有代码都会循环遍历,并且每次都会发送不同的URL。 I want to be able to call the address in the loop and then wait for it to complete and then call the completed method. 我希望能够在循环中调用该地址,然后等待它完成,然后调用完成的方法。

I have created my URI 我已经创建了我的URI

Uri address = new Uri("http://dev.virtualearth.net/REST/V1/Imagery/Metadata/OrdnanceSurvey/" + latitude + "," + longitude + "?+zl=" + zoomLevel + "&key=""");

I have then told it where to call when the operation has complete 然后,我告诉它操作完成后该去哪里打电话

WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += WebClientDownloadString_Complete;
webClient.DownloadStringAsync(address);

Then i set up what to happen when the operation has completed 然后我设置操作完成后要发生的情况

    private void WebClientDownloadString_Complete(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {

            string html = e.Result;

            string[] parts = html.Split(',');
            string[] URLs = parts[7].Split('"');
            URL = URLs[3].Replace("{subdomain}", "t0").Replace("{quadkey}", qk.Key).Replace(@"\", string.Empty);


        }
    }

Is there a way so that when the webclient calls the URL I wait till the operation has completed and it calls the completed method? 有没有一种方法可以让当Web客户端调用URL时,我等待操作完成并调用完成的方法?

The easy way to do this is to just use DownloadString instead of DownloadStringAsync . 简单的方法是只使用DownloadString而不是DownloadStringAsync The DownloadString call will block (make sure to run it on a background thread!) and you can loop as you expect. DownloadString调用将阻塞(确保在后台线程上运行它!),您可以按预期循环。

Your other option is to create a TaskCompletionSource and set it in your event handler. 您的另一个选择是创建TaskCompletionSource并将其设置在事件处理程序中。

private TaskCompletionSource<bool> currentTask;

private async Task GetURLs()
{
    while (someCondition)
    {
        currentTask = new TaskCompletionSource<bool>();
        WebClient webClient = new WebClient();
        webClient.DownloadStringCompleted += WebClientDownloadString_Complete;
        webClient.DownloadStringAsync(address);

        await currentTask;
    }
}

private void WebClientDownloadString_Complete(...)
{
    //Process completion

    //C# 6 null check
    curentTask?.TrySetValue(true);
}

"GetURLS" will block asynchronously until the tasks value is set, and then allow the while loop to continue. “ GetURLS”将异步阻止,直到设置了任务值为止,然后允许while循环继续进行。 This has the advantage of not needing an explicit background thread. 这具有不需要显式后台线程的优点。

The code that you put up already does just that - you created your WebClient, you set an event handler to its completed method, and you start the download. 您所编写的代码已经做到了这一点-创建了WebClient,将事件处理程序设置为其完成的方法,然后开始下载。 If you want to wait for it to finish, all you need to do is let your method end, and control will pass back to the Silverlight framework which will do your waiting for you. 如果您想等待它完成,您所要做的就是让方法结束,然后控制权将传递回Silverlight框架,它将由您来等待。

The other way to do this would be to use the async and await keywords, which your framework appears to support. 完成此操作的另一种方法是使用框架似乎支持的asyncawait关键字。 Simply put, you might be able to put an await keyword before your method call to DownloadStringAsync , which will cause the system to wait for the download (and go on to other tasks), pull out the string once the download completes, and continue as usual: 简而言之,您可以在对DownloadStringAsync的方法调用之前放置一个await关键字,这将导致系统等待下载(并继续执行其他任务),下载完成后拉出字符串,然后继续执行通常:

string html = await webClient.DownloadStringAsync(address);

Wanted to do this myself some time ago. 想在一段时间前自己做。 Here is how I did it: 这是我的做法:

            // create a notifier which tells us when the download is finished
            // in .net 4.5 DownloadFileTaskAsync can be used instead which simplyfies this task
            AutoResetEvent notifier = new AutoResetEvent(false);
            client.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) =>
            {
                notifier.Set();
            };

            try
            { 

                client.DownloadFileAsync(downloadUrl, destination);
                // wait for download to finish
                notifier.WaitOne();
             ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM