一开始使用一个 Winform 就足够了吗?禁用所有复选框,单击启用复选框的按钮并开始读取 tcpstream?如果您因其他原因需要两张表格,请告诉我,但我认为从您的问题中看到的情况不需要这样做。
那么我建议您使用.Net 中的任务库。这是处理多线程的“现代”方法。 BackgroundWorker 有点老派。如果您只能在.Net 2.0 上运行,则必须使用BackgroundWorker,但情况似乎并非如此(示例如下)。
此外,如果您想取消BackgroundWorker操作,这不仅仅是调用CancelAsync();
。您还需要处理e.Cancelled
flag.
backgroundWorker.WorkerSupportsCancellation = true;
private void CancelBW()
{
backgroundWorker.CancelAsync();
}
private void backgroundWorker_DoWork += ((sender, args)
{
//Handle the cancellation (in your case do this in your loop for sure)
if (e.Cancelled) //Flag is true if someone call backgroundWorker.CancelAsync();
return;
//Do your stuff.
});
没有通用的方法可以直接取消backgroundWorker
手术。你总是需要处理这个问题。
现在让我们将您的代码更改为现代 TAP 模式并制作一些您想要的东西。
private void MyForm : Form
{
private CancellationTokenSource ct;
public MyForm()
{
InitializeComponent();
checkbox1.Enable = false;
//Disable all checkboxes here.
ct = new CancellationTokenSource();
}
//Event if someone click your start button
private void buttonStart_Click(object sender, EventArgs e)
{
//Enable all checkboxes here
//This will be called if we get some progress from tcp
var progress = new Progress<string>(value =>
{
//check the behaviour of the checkboxes and write to file
file.WriteLine(value + behavior);
});
Task.Factory.StartNew(() => ListenToTcp(ct, progress as IProgress<string)); //starts the tcp listening async
}
//Event if someone click your stop button
private void buttonStop_Click(object sender, EventArgs e)
{
ct.Cancel();
//Disable all checkboxes (better make a method for this :D)
}
private void ListenToTcp(CancellationToken ct, IProgess<string> progress)
{
do
{
if (ct.IsCancellationRequested)
return;
int temp = data_feed.ReadByte(); //replaced var => temp because var is keyword
if (temp != -1)
{
data_in += (char)temp;
if (data_in.IndexOf("\r\n") != -1)
{
if (progress != null)
progress.Report(data_in); //Report the tcp-data to form thread
data_in = string.empty;
}
}
while (exit_state == false);
}
}
这个片段应该可以解决问题。我没有测试它,所以可能会出现一些语法错误:P,但原理是可行的。
最重要的是你不被允许访问gui
另一个线程中的组件然后是 gui 线程。您尝试访问
您的BackgroundWorker DoWork 中的复选框是不可能的
并抛出异常。
因此,我使用 Progress-Object 来重用我们在 Tcp-Stream 中获得的数据,返回到主线程。在那里我们可以访问复选框,构建字符串并将其写入文件。您可以找到有关 BackgroundWorker 与 Task 以及 Progress 行为的更多信息here http://blog.stephencleary.com/2013/09/taskrun-vs-backgroundworker-round-5.html.
如果您还有任何疑问,请告诉我。