如何调用需要返回值的函数来调用 WebClient?

发布于 2025-01-08 08:45:43 字数 1642 浏览 0 评论 0原文

这是我现在拥有的功能,显然不起作用。它不起作用的原因是因为 WebClient 是异步的,并且 data 在被 WebClient 填充并在 XML 读取器上崩溃之前是空的。如何在此函数中调用 WebClient,并且仍然允许它根据需要返回 ServerResult(无论是否需要外部事件处理程序)?

static public ServerResult isBarcodeCorrectOnServer(string barcode)
{
            Dictionary<string, IPropertyListItem> dict = configDictionary();

            string urlString = (string.Format("http://www.myurl.com/app/getbarcodetype.php?realbarcode={0}&type={1}", barcode, dict["type"]));

            WebClient wc = new WebClient();
            string data = "";
            wc.DownloadStringCompleted += (sender, e) =>
            {
                if (e.Error == null)
                {
                    //Process the result...
                    data = e.Result;
                }
            };
            wc.DownloadStringAsync(new Uri(urlString));

            StringReader stream = new StringReader(data);
            var reader = XmlReader.Create(stream);
            var document = XDocument.Load(reader);
            var username = document.Descendants("item");
            var theDict = username.Elements().ToDictionary(ev => ev.Name.LocalName, ev => ev.Value);

            if (theDict.ContainsKey("type") == true && theDict["type"].ToString() == dict["type"].ToString())
            {
                return ServerResult.kOnServer;
            }
            else if (theDict.ContainsKey("type") == true)
            {
                return ServerResult.kWrongType;
            }
            else
            {
                return ServerResult.kNotOnServer;
            }
        }

Here is the function I have now that obviously doesn't work. The reason it doesn't work is because WebClient is asynchronous and data is empty before it gets filled by WebClient and crashes on the XML reader. How can I call WebClient within this function and still allow it to return ServerResult as required with or without needing an external event handler?

static public ServerResult isBarcodeCorrectOnServer(string barcode)
{
            Dictionary<string, IPropertyListItem> dict = configDictionary();

            string urlString = (string.Format("http://www.myurl.com/app/getbarcodetype.php?realbarcode={0}&type={1}", barcode, dict["type"]));

            WebClient wc = new WebClient();
            string data = "";
            wc.DownloadStringCompleted += (sender, e) =>
            {
                if (e.Error == null)
                {
                    //Process the result...
                    data = e.Result;
                }
            };
            wc.DownloadStringAsync(new Uri(urlString));

            StringReader stream = new StringReader(data);
            var reader = XmlReader.Create(stream);
            var document = XDocument.Load(reader);
            var username = document.Descendants("item");
            var theDict = username.Elements().ToDictionary(ev => ev.Name.LocalName, ev => ev.Value);

            if (theDict.ContainsKey("type") == true && theDict["type"].ToString() == dict["type"].ToString())
            {
                return ServerResult.kOnServer;
            }
            else if (theDict.ContainsKey("type") == true)
            {
                return ServerResult.kWrongType;
            }
            else
            {
                return ServerResult.kNotOnServer;
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

長街聽風 2025-01-15 08:45:43

你不能没有“黑客”,你也不应该 - 拥抱异步并传递一个你想要在下载完成后执行的委托:

static public void isBarcodeCorrectOnServer(string barcode, Action<string> completed)
{
    //..
    wc.DownloadStringCompleted += (sender, e) =>
    {
       if (e.Error == null)
       {
            //Process the result...
            data = e.Result;
            completed(data);
       }
    };
    //..
}

你现在可以将所有处理代码移动到一个单独的方法中,你可以使用下载结果。

You can't without "hacks" and you shouldn't - embrace asynchrony and pass in a delegate that you want to be executed once the download is completed:

static public void isBarcodeCorrectOnServer(string barcode, Action<string> completed)
{
    //..
    wc.DownloadStringCompleted += (sender, e) =>
    {
       if (e.Error == null)
       {
            //Process the result...
            data = e.Result;
            completed(data);
       }
    };
    //..
}

You can move all your processing code now into a separate method which you call with the download result.

§对你不离不弃 2025-01-15 08:45:43

基本上你不能。或者至少你不应该这样做。您已经在专为异步 IO 设计的平台上获得了一种被设计为同步的方法。

从根本上讲,您应该设计适合该平台的代码。接受它是异步的,并让调用代码处理它。

请注意,当 C# 5 出现并且 Windows Phone 支持它时,使用 async 所有这些都将变得很多简单。您将从该方法返回一个 Task,并等待 WebClient 的结果。如果您只是为了好玩而进行开发(所以不介意使用有一些错误的 CTP,并且可能不适用于市场应用程序),您可以 今天就这样做

You can't, basically. Or at the very least you shouldn't. You've got a method which is designed to be synchronous, on a platform which is designed for asynchronous IO.

Fundamentally, you should design your code to work with the platform. Accept that it will be asynchronous, and make the calling code deal with that.

Note that when C# 5 comes out and when it's supported by Windows Phone, all of this will be a lot simpler using async. You'd return a Task<ServerResult> from the method, and await the result of the WebClient. If you're only developing for fun (so don't mind working with a CTP which has some bugs, and may not be valid to ship for marketplace apps) you can do that today.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文