如何调用需要返回值的函数来调用 WebClient?
这是我现在拥有的功能,显然不起作用。它不起作用的原因是因为 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你不能没有“黑客”,你也不应该 - 拥抱异步并传递一个你想要在下载完成后执行的委托:
你现在可以将所有处理代码移动到一个单独的方法中,你可以使用下载结果。
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:
You can move all your processing code now into a separate method which you call with the download result.
基本上你不能。或者至少你不应该这样做。您已经在专为异步 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 aTask<ServerResult>
from the method, andawait
the result of theWebClient
. 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.