这应该很简单,但我找不到足够的术语来搜索......我是C#的新手,我正在尝试创建一个简单的应用程序来编写Web服务的返回。 / p>
我遇到了使用Thread的需要...将参数传递给线程相当容易,我找不到从Threaded方法返回的方法并更新我的UI以显示结果(实际上没有现在的实际结果)
活动:
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
minhaSigla = Sigla.Text;
Task.Factory.StartNew(() => GetQuoteAndUpdateText(minhaSigla));
tb1.Text = "UIElement-TO-UPDATE";
}
然后是Threaded方法
private string GetQuoteAndUpdateText(string sign)
{
string SoapEnvelope = "";
SoapEnvelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
SoapEnvelope += "<soap:Envelope ";
SoapEnvelope += "xmlns:xsi = \"http://www.w3.org/2001/XMLSchema-instance\" ";
SoapEnvelope += "xmlns:xsd= \"http://www.w3.org/2001/XMLSchema\" ";
SoapEnvelope += "xmlns:soap= \"http://schemas.xmlsoap.org/soap/envelope/\">";
SoapEnvelope += "<soap:Body>";
SoapEnvelope += " <GetQuote xmlns=\"http://www.webserviceX.NET/\"> ";
SoapEnvelope += " <symbol>" + sign + "</symbol> ";
SoapEnvelope += " </GetQuote> ";
SoapEnvelope += "</soap:Body>";
SoapEnvelope += "</soap:Envelope>";
EndpointAddress endpoint = new EndpointAddress("http://www.webservicex.net/stockquote.asmx");
BasicHttpBinding basicbinding = new BasicHttpBinding();
basicbinding.SendTimeout = new TimeSpan(3000000000);
basicbinding.OpenTimeout = new TimeSpan(3000000000);
stockbyname.StockQuoteSoapClient sbn = new stockbyname.StockQuoteSoapClient(basicbinding, endpoint);
XmlDocument xmlDocument = new XmlDocument();
return sbn.GetQuote(SoapEnvelope);
}
此外,我们非常感谢任何信息,甚至评论我的代码有多糟糕:P
答案 0 :(得分:4)
如果没有了解所有有趣的async/await内容,您可以使用ContinueWith的Task方法处理返回的信息。
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
minhaSigla = Sigla.Text;
var quoteGetterTask = Task.Factory.StartNew(() => GetQuoteAndUpdateText(minhaSigla));
quoteGetterTask.ContinueWith(task =>
{
var theResultOfYourServiceCall = task.Result;
//You'll need to use a dispatcher here to set the value of the text box (see below)
tb1.Text = theResultOfYourServiceCall; //"UIElement-TO-UPDATE";
});
}
正如我在上面的代码示例中提到的,根据您使用的UI技术,您需要使用调度程序来避免获得非法的跨线程访问异常。
WinForms .ContinueWith
内部表达式的示例(使用Invoke的Control方法)
task =>
{
var theResultOfYourServiceCall = task.Result;
tb1.Invoke(new Action(() => tb1.Text = theResultOfYourServiceCall));
}
.ContinueWith
内部表达式的WPF示例(使用WPF的Dispatcher)
task =>
{
var theResultOfYourServiceCall = task.Result;
tb1.Dispatcher.Invoke(DispatcherPriority.Normal,
new Action(() => tb1.Text = theResultOfYourServiceCall));
}
Silverlight / Windows Phone .ContinueWith
中的表达式示例(使用Silverlight的Dispatcher)
task =>
{
var theResultOfYourServiceCall = task.Result;
tb1.Dispatcher.BeginInvoke(() => tb1.Text = theResultOfYourServiceCall);
}
Windows Store在.ContinueWith
(使用CoreDispatcher)
task =>
{
var theResultOfYourServiceCall = task.Result;
tb1.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => tb1.Text = theResultOfYourServiceCall);
}
答案 1 :(得分:2)
更常见的是,您需要在UI线程上执行任务,因为这样可以更新您的控件。
Task<string>.Factory.StartNew(() => GetQuoteAndUpdateText(minhaSigla)).ContinueWith(s=> tb1.Text = s,
TaskScheduler.FromCurrentSynchronizationContext());
ps:你也可以使用await&amp; asnet in .net 4.5
答案 2 :(得分:1)
其他人提到async
/ await
,但这是一个简单的例子:
private async void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
minhaSigla = Sigla.Text;
string result = await GetQuoteAndUpdateTextAsync(minhaSigla);
tb1.Text = "UIElement-TO-UPDATE";
}
private Task<string> GetQuoteAndUpdateTextAsync(string sign)
{
string SoapEnvelope = "";
SoapEnvelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
SoapEnvelope += "<soap:Envelope ";
SoapEnvelope += "xmlns:xsi = \"http://www.w3.org/2001/XMLSchema-instance\" ";
SoapEnvelope += "xmlns:xsd= \"http://www.w3.org/2001/XMLSchema\" ";
SoapEnvelope += "xmlns:soap= \"http://schemas.xmlsoap.org/soap/envelope/\">";
SoapEnvelope += "<soap:Body>";
SoapEnvelope += " <GetQuote xmlns=\"http://www.webserviceX.NET/\"> ";
SoapEnvelope += " <symbol>" + sign + "</symbol> ";
SoapEnvelope += " </GetQuote> ";
SoapEnvelope += "</soap:Body>";
SoapEnvelope += "</soap:Envelope>";
EndpointAddress endpoint = new EndpointAddress("http://www.webservicex.net/stockquote.asmx");
BasicHttpBinding basicbinding = new BasicHttpBinding();
basicbinding.SendTimeout = new TimeSpan(3000000000);
basicbinding.OpenTimeout = new TimeSpan(3000000000);
stockbyname.StockQuoteSoapClient sbn = new stockbyname.StockQuoteSoapClient(basicbinding, endpoint);
XmlDocument xmlDocument = new XmlDocument();
return sbn.GetQuoteAsync(SoapEnvelope);
}
请注意它与您现有方法的相似之处。这就是async
的力量。