C# backgroundworker在ProgressChange时给出了跨线程异常?
我有文件传输应用程序(服务器客户端)TCP[.net 4] 为什么backgroundworker在中给我一个异常(backgroundWorker1\u ProgressChanged) 客户端将具有目标路径(文件应保存到其中)和文件大小的命令发送到服务器以开始接收该文件。。所以一旦服务器接受了这个命令。。它将呼吁:C# backgroundworker在ProgressChange时给出了跨线程异常?,c#,winforms,exception,backgroundworker,multithreading,C#,Winforms,Exception,Backgroundworker,Multithreading,我有文件传输应用程序(服务器客户端)TCP[.net 4] 为什么backgroundworker在中给我一个异常(backgroundWorker1\u ProgressChanged) 客户端将具有目标路径(文件应保存到其中)和文件大小的命令发送到服务器以开始接收该文件。。所以一旦服务器接受了这个命令。。它将呼吁: fileTransfer1.Receive(destPath, fileSize); 此方法在form1.cs中自己的线程中运行: private void Job(objec
fileTransfer1.Receive(destPath, fileSize);
此方法在form1.cs中自己的线程中运行:
private void Job(object o)
{
Socket client = (Socket)o;
NetworkStream stream = new NetworkStream(client);
StreamReader sr = new StreamReader(stream);
string cmd = null;
while ((cmd = sr.ReadLine()) != null)
{
string[] command = cmd.Split('<');
switch (command[0])
{
case "receive":
fileTransfer1.Receive(command[1], Convert.ToInt64(command[2]));
break;
default:
break;
}
}
我知道那个异常,我知道我必须使用(委托/调用)这个东西。。但是我知道那个幕后工作者就是为了这个。。加。。我有相同的代码,但是这里的服务器向客户端发送了一个文件。。而且它也不例外。。它工作正常,表单显示了应该显示的详细信息。那么,为什么我在收到文件时会出现此异常呢???
注意:receive方法工作正常。之所以会出现此错误,是因为
backgroundWorker1\u ProgressChanged()
运行的线程与创建labelRemaining
控件的线程不同。假设您在主UI线程上创建了labelRemaining
控件,则需要:
- 从主线程执行
或backgroundWorker1.RunWorkerAsync(作业)
- 在
内部,使用Dispatcher对主线程上的backgroundWorker1\u ProgressChanged
对象执行更改,如下所示:labelRemaining
case "receive":
fileTransfer1.Receive(command[1], Convert.ToInt64(command[2]));
break;
也在同一线程中运行。。这意味着代码的其余部分也在该线程中运行。。
所以我把这行改成这样:
case "receive":
Action a = () => fileTransfer1.Receive(command[2], Convert.ToInt64(command[3]));
Invoke(a);
break;
现在将通知UI线程运行其余的接收代码。。这解决了我的问题。哪个表单托管BackgroundWorker?是否有一个“下载进度”弹出窗口,如Chrome或IE所示?@ChrisShain不,这是一个主窗体中的用户控件。。接收文件并显示接收进度的。n/m在这种异常情况下这无关紧要。我想你可能是对的。。因为在收到案件时。。从客户端接收命令的方法正在线程中运行,因此它在接收命令的同一线程中调用backgroundworker.runasync()。。这就是我得到这个例外的原因吗?我很确定这就是原因。否则你就不会从后台工作人员那里得到例外情况。@MurHafSoz那太好了,如果我的回答对你有帮助,那么请将其标记为例外情况。谢谢,你说得对。。你提醒我,我在一个线程中运行作业方法,它帮助我思考如何解决问题。。但是我应该让其他有同样问题的人清楚地知道答案。。我要记下我的答案。
labelRemaining.Text = CnvrtUnit(fileSize - sum);
case "receive":
fileTransfer1.Receive(command[1], Convert.ToInt64(command[2]));
break;
case "receive":
Action a = () => fileTransfer1.Receive(command[2], Convert.ToInt64(command[3]));
Invoke(a);
break;