C# 使用串行端口通信发送批量消息
我可以通过书面形式从我的申请中发送信息C# 使用串行端口通信发送批量消息,c#,multithreading,sms,serial-port,C#,Multithreading,Sms,Serial Port,我可以通过书面形式从我的申请中发送信息 port.WriteLine("AT+CMGS=\"" + m.Groups[2].Value + "\""); port.Write(txt_msgbox.Text + char.ConvertFromUtf32(26)); 这很好。但现在我想向一组数字发送批量消息。我使用此循环向一组数字发送消息: foreach (ListViewItem item in bufferedListView1.Items) { string lname = b
port.WriteLine("AT+CMGS=\"" + m.Groups[2].Value + "\"");
port.Write(txt_msgbox.Text + char.ConvertFromUtf32(26));
这很好。但现在我想向一组数字发送批量消息。我使用此循环向一组数字发送消息:
foreach (ListViewItem item in bufferedListView1.Items)
{
string lname = bufferedListView1.Items[i].Text;
string lno = bufferedListView1.Items[i].SubItems[1].Text;
string gname = bufferedListView1.Items[i].SubItems[2].Text;
string line = lname + "@" + lno + "@" + gname;
if (gname.Contains(sgroup))
{
var m = Regex.Match(line, @"([\w]+)@([+\d]+)@([\w]+)");
if (m.Success)
{
port.WriteLine("AT+CMGS=\"" + m.Groups[2].Value + "\"");
port.Write(txt_msgbox.Text + char.ConvertFromUtf32(26));
Thread.Sleep(4000);
}
sno++;
}
i++;
}
这也很有效。但问题在于UI,在相当长的一段时间内变得不负责任。有更好的方法吗 使用
BackgroundWorker
-它们非常易于使用,并以封装的方式管理线程。这个类的好处是,如果您希望能够取消流程,它支持取消,并且它支持报告进度,我将在这里展示这两个方面。最后,这个类的好处是,当它报告进度时,它会正确地切换线程,确保您不是在单独的线程上向UX写入代码,但是DoWork
事件处理程序中的代码仍然在单独的线程上正确管理
您将执行以下操作
// in this example this is scoped to the class, but just scope it appropriately
private BackgroundWorker worker = new BackgroundWorker();
......
// because I don't really know anything about how your program is structured I'm not sure
// where you want to place all of the definitions OR where you want to place RunWorkerAsync
// but you want the definitions to happen ONCE and the RunWorkerAsync to be where the USER
// initiates it
// this will allow you to consume the ProgressChanged event
worker.WorkerReportsProgress = true;
// this will allow you to set the CancellationPending property
worker.WorkerSupportsCancellation = true;
worker.DoWork += (o, args) =>
{
foreach (ListViewItem item in bufferedListView1.Items)
{
string lname = bufferedListView1.Items[i].Text;
string lno = bufferedListView1.Items[i].SubItems[1].Text;
string gname = bufferedListView1.Items[i].SubItems[2].Text;
string line = lname + "@" + lno + "@" + gname;
if (gname.Contains(sgroup))
{
var m = Regex.Match(line, @"([\w]+)@([+\d]+)@([\w]+)");
if (m.Success)
{
port.WriteLine("AT+CMGS=\"" + m.Groups[2].Value + "\"");
port.Write(txt_msgbox.Text + char.ConvertFromUtf32(26));
Thread.Sleep(4000);
}
sno++;
}
i++;
}
}
worker.ProgressChanged += (s, args) =>
{
// set some progress here, the ProgressChangedEventArgs inherently supports an integer
// progress via the ProgressPercentage property
}
worker.RunWorkerCompleted += (s, args) =>
{
// with the RunWorkerCompletedEventArgs class you can check for errors via Error, did
// cancellation occur via Cancelled, and you can even send a complex result via the Result
// property - whatever you need
}
// this starts the work in the DoWork event handler
worker.RunWorkerAsync();
以下是有关此问题的Microsoft文档的详细信息。使用bufferedListView1。worker.DoWork中的项会导致此异常-
跨线程操作无效:控件“bufferedListView1”是从创建它的线程以外的线程访问的。
@Cdeez-是的,您是对的,我没有注意到其中的循环是正确的。您需要将ListViewItemCollection
转换为可以传递到args
的东西,这是一种类似于ListViewItem
的基本元素,因为它与ListViewItem
非常类似,然后更改对RunWorkerAsync
的调用以传入该变量。@Cdeez-还有,一旦你转换了代码并开始工作,编辑我的问题并发布社区的更改。