英文:
asp.net webforms control not updating after being modified in httpclient call/response
问题
I'm trying to make a quick and dirty c# asp.net webforms app. Nothing fancy.
新建WebForms项目,打开default.aspx.cs的设计器。
然后从工具栏拖动一个按钮和一个文本框到页面上。
然后在设计器中双击按钮以获取点击方法,这是100%可重现的。这个应用程序实际上非常简单。
这可能是一个非常基本的问题,我怀疑这是另一个线程的更新问题。
在我的default.aspx.cs文件中,我正在访问一个WebAPI,得到"OK"的返回。我希望textbox1的文本从"?"变为从Web服务返回的"OK"。
我点击按钮,一切都如预期执行,我在调试器中看到文本已更改,但在网页上它仍然是旧的"?"值。
我猜想这是因为我在另一个线程上更新它?
protected void Button1_Click(object sender, EventArgs e)
{
try
{
// 创建一个HttpClient实例
HttpClient client = new HttpClient();
// 异步发送请求并在完成后继续
client.GetAsync("http://localhost:44331/DoCdssLoginTests?sAdName=bob.bob").ContinueWith(
(requestTask) =>
{
// 从已完成任务获取HTTP响应
HttpResponseMessage response = requestTask.Result;
// 检查响应是否成功,或引发异常
response.EnsureSuccessStatusCode();
// 异步读取响应为JsonValue
response.Content.ReadAsStringAsync().ContinueWith(
(readTask) =>
{
var result = readTask.Result;
// 对结果进行一些操作
TextBox1.Text = result.ToString();
Button1.Text = result.ToString();
});
});
}
catch (Exception ex)
{
TextBox1.Text = ex.Message;
throw;
}
}
有人能看出我做错了什么吗?我也尝试在按钮上更新文本,但在页面刷新时它似乎也已更改,但未改变。
英文:
I'm trying to make a quick and dirty c# asp.net webforms app. Nothing fancy.
new webforms project, open the designer for default.aspx.cs
Then drag a button and a textbox off the toolbar onto the page.
Then double-click on the button in the designer to get the click method and it's 100% reproducible. The app is literally as simple as you can get.
This may be a really basic issue, I suspect it's an update on another thread issue.
In my default.aspx.cs file, I'm hitting a webAPi, getting "OK" back. I want the text of the textbox1 to change from "?" to "OK" returned from the web service.
I click the button everything executes as expected, I see the text get changed in the debugger, but on the webpage it's still the old "?" value.
I'm guessing it's because I'm updating it in a response on a different thread?
protected void Button1_Click( object sender, EventArgs e )
{
try
{
// Create an HttpClient instance
HttpClient client = new HttpClient();
// Send a request asynchronously continue when complete
client.GetAsync( "http://localhost:44331/DoCdssLoginTests?sAdName=bob.bob" ).ContinueWith(
( requestTask ) =>
{
// Get HTTP response from completed task.
HttpResponseMessage response = requestTask.Result;
// Check that response was successful or throw exception
response.EnsureSuccessStatusCode();
// Read response asynchronously as JsonValue
response.Content.ReadAsStringAsync().ContinueWith(
( readTask ) =>
{
var result = readTask.Result;
//Do something with the result
TextBox1.Text = result.ToString();
Button1.Text = result.ToString();
} );
} );
}
catch ( Exception ex )
{
TextBox1.Text = ex.Message;
throw;
}
Can anyone see what I'm doing wrong? I tried updating the text on the button too, but it also looks like it got changed and is unaltered on the page refresh.
答案1
得分: 0
好的,这是翻译好的部分:
"Okay I figured it out." - 好的,我明白了。
"Vadims comment about ContinueWith running in its own thread was the key." - Vadims有关ContinueWith在其自己的线程中运行的评论是关键。
"I pulled the AsynchHelper from this post:" - 我从这篇帖子中提取了AsynchHelper:
"and added it to the class." - 并将它添加到了类中。
"and then changed the method thusly:" - 然后修改了方法如下:
"protected void Button1_Click( object sender, EventArgs e )" - 受保护的void Button1_Click( object sender, EventArgs e )方法:
"internal static class AsyncHelper" - 内部静态类AsyncHelper:
"This eliminated the cross thread updating (which is know to be an issue) and simplified away the asynch call in a synchronous method." - 这消除了跨线程更新(已知是一个问题),并简化了异步调用在同步方法中的使用。
"Now it's working as expected." - 现在它按预期工作。
英文:
Okay I figured it out.
Vadims comment about ContinueWith running in its own thread was the key.
I pulled the AsynchHelper from this post:
and added it to the class.
and then changed the method thusly:
protected void Button1_Click( object sender, EventArgs e )
{
try
{
string buffer = string.Empty;
// Create an HttpClient instance
HttpClient client = new HttpClient();
var result = AsyncHelper.RunSync<string>( () => client.GetStringAsync( "http://localhost:44331/DoCdssLoginTests?sAdName=bob.bob" ) );
TextBox1.Text = result;
}
catch ( Exception ex )
{
TextBox1.Text = ex.Message;
throw;
}
}
internal static class AsyncHelper
{
private static readonly TaskFactory _myTaskFactory = new
TaskFactory( CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default );
public static TResult RunSync<TResult>( Func<Task<TResult>> func )
{
return AsyncHelper._myTaskFactory
.StartNew<Task<TResult>>( func )
.Unwrap<TResult>()
.GetAwaiter()
.GetResult();
}
public static void RunSync( Func<Task> func )
{
AsyncHelper._myTaskFactory
.StartNew<Task>( func )
.Unwrap()
.GetAwaiter()
.GetResult();
}
}
This eliminated the cross thread updating (which is know to be an issue) and simplified away the asynch call in a synchronous method.
Now it's working as expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论