在form1我有这个公共方法:
public void CombindedStringFix()
{
BeginUpdate();
label3.Text = SaveOldHtml.HtmlLoadedFileNumber.ToString();
richTextBox1.Clear();
List<string> newText1 = new List<string>();
label1.Select();
scrollerList = new List<string>(Filters.newTextWithoutLinks);
scrollerText = string.Join(Environment.NewLine, scrollerList);
scroller1.TextToScroll = scrollerText;
combindedString = string.Join(Environment.NewLine, SaveOldHtml.newText);
richTextBox1.Text = combindedString;
string[] rlines = richTextBox1.Lines;
timer3.Start();
richTextBox1.SelectionStart = 0;
richTextBox1.SelectionLength = rlines[0].Length;
richTextBox1.SelectionColor = Color.Red;
richTextBox1.Select(rlines[0].Length, rlines[1].Length + 1);
richTextBox1.SelectionColor = Color.Green;
EndUpdate();
}
然后在新类我调用这个方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Timers;
using System.Windows.Forms;
namespace ScrollLabelTest
{
class SaveOldHtml
{
private static Form1 frm1 = null;
private static int count;
private static System.Timers.Timer _timer = new System.Timers.Timer();
private static string page;
public static List<string> newText = new List<string>();
public static int HtmlLoadedFileNumber = 0;
public SaveOldHtml(string DirectoryToSave,int count, string contents)
{
System.IO.File.WriteAllText(DirectoryToSave + "Page" + count.ToString("D6")
+ ".html", contents);
}
public SaveOldHtml(string DirectoryToSave, List<string> newTextList, int count)
{
using (StreamWriter myStream = new StreamWriter(DirectoryToSave + "newTextList" + count.ToString("D6")
+ ".txt"))
{
for (int i = 0; i < newTextList.Count; i++)
{
myStream.WriteLine(newTextList[i]);
}
}
}
public static void Start(Form1 form)
{
frm1 = form;
_timer.Elapsed += _timer_Elapsed;
_timer.Interval = 10000;
count = 5;
LoadOldHtmlFiles();
frm1.CombindedStringFix();
_timer.Start();
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Stop();
LoadOldHtmlFiles();
frm1.CombindedStringFix();
_timer.Start();
}
private static void LoadOldHtmlFiles()
{
page = File.ReadAllText(@"c:\temp\OldHtml\page" + count.ToString("D6") + ".html");
ListsExtractions.OffExtractions(@"c:\temp\OldHtml\page" + count.ToString("D6") + ".html", page, newText);
count ++;
HtmlLoadedFileNumber++;
}
}
}
一旦我在类的Start方法中调用CombindedStringFix方法,它就可以正常工作并完成CombindedStringFix中的所有行 . 我使用了一个breakpoiont,它做到了这一切 .
但是下次当它在新类中调用计时器tick事件中的方法时,我使用断点并且一旦它在第一行BegingUpdate();它只是contine而且永远不会在计时器tick事件中再次停止,并且永远不会超越BeginUpdate();
即使我删除了BeginUpdate();所以它将成为第一行,然后继续它将永远不会移动到下一行/ s .
我现在看到我在计时器刻度事件中遇到异常:
跨线程操作无效:控制从其创建的线程以外的线程访问的“Form1”
System.InvalidOperationException was caught
HResult=-2146233079
Message=Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.Control.get_Handle()
at ScrollLabelTest.Form1.BeginUpdate() in e:\scrolllabel\ScrollLabel\ScrollLabel\Form1.cs:line 69
at ScrollLabelTest.Form1.CombindedStringFix() in e:\scrolllabel\ScrollLabel\ScrollLabel\Form1.cs:line 280
at ScrollLabelTest.SaveOldHtml._timer_Elapsed(Object sender, ElapsedEventArgs e) in e:\scrolllabel\ScrollLabel\ScrollLabel\SaveOldHtml.cs:line 64
InnerException:
我想这与frm1变量有关 .
2 回答
问题很可能是在Elapsed事件中某处发生了异常,并且Timer永远不会再次启动 . 您可以设置一个断点,并在第一次进入时查看断点,以查看它是否失败 . 或者,您可以将其编码为开始备份,无论如何:
由于您确认发生了跨线程异常,我建议您阅读:
How to: Make Thread-Safe Calls to Windows Forms Controls
这是他们的演示,以防链接被破坏:
我将尝试回答这个问题,但如果没有完整的背景,那就有点粗糙了 .
CombindedStringFix()
方法中你看起来像是一个名为timer3
的计时器对象 . 此计时器的名称似乎与SaveOldHtml
类中的计时器名称不匹配,我想知道您是否有两个可能会混淆的计时器 .我知道不回答这个问题是不好的形式,但是如果没有更多细节/更多来源,这是我能够集合的最好的 . 任何更多的背景,我可以提供更多的帮助!