asp.net webforms 控件在通过HttpClient调用/响应后未更新。

huangapple go评论73阅读模式
英文:

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:

https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c

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.

huangapple
  • 本文由 发表于 2023年3月7日 07:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定