如何从其他线程更新ASP.NET中的textBox中的值?

时间:2011-03-05 19:20:51

标签: asp.net wcf callback wcf-callbacks

我在IIS7.5和WCF回调技术上使用ASP.NET 4.0。我回调没问题。 wcf服务可以在Web客户端中触发回调方法,但它似乎在另一个具有UI线程的线程上。

public partial class _Default : System.Web.UI.Page, IServiceCallback
{
    private IService proxy = null;
    private static TextBox _textBoxtest;

    protected void Page_Load(object sender, EventArgs e)
    {
        _textBoxtest = TextBox1;
    }      

    protected void Button1_Click(object sender, EventArgs e)
    {
        //then server will call back to FireCallBackFromServer
        proxy.CallService(type, "someObject");
    }

    #region IServiceCallback Members

    public void FireCallBackFromServer(string txt)
    {
        TextBox1.Text = txt; <-- the value does not update on textBox
    }

    #endregion
}

请帮我思考如何从回调事件更新我的textBox。

谢谢。

2 个答案:

答案 0 :(得分:2)

这是WCF回调的工作原理。每个回调调用都由自己的线程提供。我认为发生这种情况的原因是因为你没有SynchronizationContext会将请求发送回当前线程(并希望当前的页面实例)。相反的示例是WPF或WinForm应用程序中使用的回调。默认情况下,这些应用程序中的UI线程为SynchronizationContext,因此如果您在UI线程中打开服务代理,则回调请求将被路由回UI线程 - 它有时会导致另一个问题,因此您可以关闭SynchronizationContext的使用在ServiceBehaviorAttribute

但即使你解决了这个问题,你也会在ASP.NET中处理同样的问题。每个ASP.NET请求都会创建一个新的处理程序实例。因此,浏览器的每个请求都将创建新的页面实例。

我相信如果客户端是ASP.NET,那么WCF回调没有意义,因为我仍然没有看到任何有效的实现。

答案 1 :(得分:0)

我遇到过这个问题,其中只有UI线程可以在使用WCF回调的WPF应用程序中执行UI更新。我在ASP.NET中做的工作不多,所以我不是100%肯定答案是一样的,但问题看起来很相似。

我解决问题的方法是使用Dispatcher和lambdas将更改发送到UI线程。放入代码的上下文,它看起来像

public void FireCallBackFromServer(string txt)
{
    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => TextBox1.Text = txt;));
}

这应该将文本框的内容更新为回调中提供的文本。试一试,看看你怎么走。