ASP.NET中FileSystemWatcher触发后TextBox值无法在客户端显示
问题分析与解决:FileSystemWatcher更新TextBox后客户端无变化
核心原因
- WebForm基于请求-响应模型:只有客户端发起请求(如页面回发、AJAX请求)时,服务器才会生成新的HTML并返回给客户端,更新页面内容。
- FileSystemWatcher的事件在后台线程触发:
OnFileCreated事件不属于任何页面请求的生命周期,此时修改服务器控件txtName.Text仅改变了服务器内存中的控件属性,不会触发页面重新渲染和内容推送,客户端自然看不到更新。
可行解决方案
方案1:AJAX定时轮询(简单易实现)
客户端定期向服务器发送请求,获取最新的文件内容并更新TextBox。
页面脚本(ASPX)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> // 每2秒轮询一次服务器 setInterval(function() { $.ajax({ url: '<%= Request.Url.AbsolutePath %>/GetLatestName', type: 'POST', contentType: 'application/json; charset=utf-8', dataType: 'json', success: function(res) { if (res.d) { $('#<%= txtName.ClientID %>').val(res.d); } } }); }, 2000); </script>
后台WebMethod(C#)
[System.Web.Services.WebMethod] public static string GetLatestName() { string targetFile = "你的目标文件路径"; if (!File.Exists(targetFile)) return string.Empty; string[] lines = File.ReadAllLines(targetFile); if (lines.Length >= 3 && !string.IsNullOrEmpty(lines[1])) { return lines[1]; } return "Not a valid value"; }
方案2:SignalR实时推送(实时性高)
通过SignalR建立服务器与客户端的持久连接,当文件变化时主动推送更新到客户端。
1. 安装SignalR NuGet包
Install-Package Microsoft.AspNet.SignalR
2. 创建SignalR Hub类
public class FileUpdateHub : Hub { public static void PushNameUpdate(string name) { var hubContext = GlobalHost.ConnectionManager.GetHubContext<FileUpdateHub>(); hubContext.Clients.All.updateTextBox(name); } }
3. 配置SignalR(Global.asax)
protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHubs(); // 其他初始化逻辑 }
4. 页面添加SignalR脚本(ASPX)
<script src="Scripts/jquery.signalR-2.4.2.min.js"></script> <script src="/signalr/hubs"></script> <script> $(function () { var fileHub = $.connection.fileUpdateHub; // 接收服务器推送的更新 fileHub.client.updateTextBox = function (name) { $('#<%= txtName.ClientID %>').val(name); }; // 启动连接 $.connection.hub.start(); }); </script>
5. 修改FileSystemWatcher事件处理
private void OnFileCreated(object sender, FileSystemEventArgs e) { if(e.Name != fileName) return; try { if(!File.Exists(fileName)) return; string[] lines = File.ReadAllLines(fileName); if (lines.Length >= 3) { string content = string.IsNullOrEmpty(lines[1]) ? "Not a valid value" : lines[1]; // 推送更新到客户端 FileUpdateHub.PushNameUpdate(content); } } catch (Exception ex) { errorTxt.Text = ex.ToString(); } }
方案3:触发页面回发(不推荐)
通过脚本触发页面回发,刷新整个页面来更新内容,用户体验较差,仅适合简单场景。
private void OnFileCreated(object sender, FileSystemEventArgs e) { // ... 文件读取逻辑 string name = lines[1]; // 保存最新值到Session Session["LatestName"] = name; // 触发页面回发 ScriptManager.RegisterStartupScript(this, GetType(), "autoPostback", "__doPostBack('','');", true); } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 初始化FileSystemWatcher watcher = new FileSystemWatcher(path); watcher.Created += OnFileCreated; watcher.Changed += OnFileCreated; watcher.InternalBufferSize = 64000; watcher.Filter = "*.txt"; watcher.EnableRaisingEvents = true; } else { // 回发时更新TextBox if (Session["LatestName"] != null) { txtName.Text = Session["LatestName"].ToString(); Session.Remove("LatestName"); } } }
内容的提问来源于stack exchange,提问作者karan ugale
相关产品推荐
相关产品推荐

