从另一个线程/类

时间:2017-09-28 16:51:33

标签: c# asp.net web-applications

我正在使用旧的asp.net Web应用程序,我在尝试从另一个线程将文本写入引导文本框时遇到问题。我已将网络应用简化为以下代码:

Default.aspx.cs:

using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;
using AspNet;

namespace ProblemApp
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void UpdateButton_Click(object sender, EventArgs e)
        {
            if (this.TextBox1.Text == "")
            {
                TextBox1.Text = "TEST";
            }
        }

        protected void UpdateButton2_Click(object sender, EventArgs e)
        {
            AutoLogControl NewAutoLogger = new AutoLogControl();
            Thread AutoLoggerThread = new Thread(() => NewAutoLogger.StartAutoLogger(sender));
            AutoLoggerThread.Start();
        }
    }
}

Autolog.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;

namespace ProblemApp
{
    public partial class AutoLogControl : _Default
    {
        public void StartAutoLogger(object sender)
        {
            //would normally listen for a condition to be met, but for
            //this example, just set the Textbox. This is where my issue
            //is. TextBox is null.
            TextBox1.Text = "TEST 2";
        }
    }
}

正如您所看到的,我需要从StartAutoLogger()设置TextBox,但是当我尝试时我得到一个空引用。我已经尝试了其他几个解决方案,例如在_Default中创建一个公共方法来设置文本,但这也不起作用。如果您需要,可以使用以下支持文件。

Default.aspx的:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ProblemApp._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">


    <div class="row panel-body verticle-align">
        <div class="col-lg-3">
            <h4><span class="label label-default"> Text Box : </span></h4>
        </div>
        <div class="col-lg-9">
            <asp:TextBox ID ="TextBox1" name="Textbox1" runat="server" Width="100%" />
        </div>
    </div>
    <div class="row btn-block panel-body">
        <div class="col-lg-4">
            <asp:Button ID="UpdateButton" runat="server" OnClick="UpdateButton_Click" Text="Update" CssClass="btn btn-default" />
        </div>
                <div class="col-lg-4">
            <asp:Button ID="UpdateButton2" runat="server" OnClick="UpdateButton2_Click" Text="Update 2" CssClass="btn btn-default" />
        </div>
    </div>

</asp:Content>

Default.aspx.designer.cs:

namespace ProblemApp {


public partial class _Default {

    protected global::System.Web.UI.WebControls.TextBox TextBox1;

    protected global::System.Web.UI.WebControls.Button UpdateButton;

    protected global::System.Web.UI.WebControls.Button UpdateButton2;
}
}

1 个答案:

答案 0 :(得分:0)

你的遗产可能会倒退。在您引用时AutoLogControl

TextBox1.Text = "TEST 2";

你真的在打电话:

AutoLogControl.TextBox1.Text = "TEST 2";

不是对页面上实际TextBox的引用:

_Default.TextBox1;

您正在传递sender对象作为参数,所以您可以:

  1. 将发件人转换为适当的类型

  2. 获取相关页面

  3. 搜索所需的控件(可能指定其他参数)

  4. 如果您这样做,AutoLogClass不应继承_Default,而应继承System.Web.UI.UserControl,并且应将[{1}}公开为静态方法。

    或者,您可以让_Default继承自AutoLogControl,而是使用:

    StartAutoLogger

    虽然我不知道Thread AutoLoggerThread = new Thread(() => this.StartAutoLogger(sender)); AutoLoggerThread.Start(); 的背景,但可能不合适。

    在任何一种情况下,目前AutoLogClass 都是 AutoLogClass,因此使用_Default对其进行实例化会创建 new {{1控件与原始new不同的页面。引用控件不会抛出编译器错误,因为它们确实存在于_Default的父级中,但它们未初始化,ergo:_Default