如何在委托的if条件中使用.Equals("string")?解决跨线程与空引用异常
解决BackgroundWorker跨线程访问TextBox的空引用问题
首先得说你原来的代码问题出在哪:你用了Action类型的委托,这玩意儿是无返回值的,所以scrapeType.Invoke(...)执行完返回的是null,你非要把null强转成bool,这不就触发“对象引用未设置到对象的实例”异常了嘛!而且跨线程访问UI控件必须在UI线程操作,这点你方向是对的,但委托类型选错了。
给你两种靠谱的解决方法:
方法1:用带返回值的委托获取TextBox的文本判断结果
把Action换成Func<bool>(有返回值的委托),这样Invoke就能返回Equals的布尔结果了,代码改成这样:
// 正确获取跨线程的文本判断结果 bool isScrapeUrls = (bool)scrapeType.Invoke(new Func<bool>(() => { return scrapeType.Text.Equals("Scrape URLS"); })); // 然后用这个bool值做判断 if (isScrapeUrls) { // 你的业务逻辑代码 }
嫌代码长?可以简化成一行:
bool isScrapeUrls = (bool)scrapeType.Invoke(() => scrapeType.Text.Equals("Scrape URLS"));
这里要注意:确保scrapeType控件已经在UI线程初始化完成(不是null),如果怕出问题,可以加个null判断:
if (scrapeType != null) { bool isScrapeUrls = (bool)scrapeType.Invoke(() => scrapeType.Text.Equals("Scrape URLS")); if (isScrapeUrls) { // 执行你的逻辑 } }
方法2:提前在UI线程获取值,再传给BackgroundWorker
其实BackgroundWorker支持通过RunWorkerAsync()传参数,你可以在启动Worker之前,先在UI线程把TextBox的判断结果存好,再传给DoWork事件,这样完全不用在DoWork里跨线程操作UI,更简单安全:
// 在UI线程(比如按钮点击事件里)先获取判断结果 bool scrapeUrlsFlag = scrapeType.Text.Equals("Scrape URLS"); // 把结果作为参数传给BackgroundWorker backgroundWorker1.RunWorkerAsync(scrapeUrlsFlag); // 然后在DoWork事件里直接用参数 private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { bool isScrapeUrls = (bool)e.Argument; if (isScrapeUrls) { // 你的业务逻辑 } }
这种方法我更推荐,因为尽量减少跨线程操作UI的场景,能避免很多潜在问题。
内容的提问来源于stack exchange,提问作者nav
相关产品推荐
相关产品推荐

