Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取跨线程操作异常_C#_Exception - Fatal编程技术网

C# 获取跨线程操作异常

C# 获取跨线程操作异常,c#,exception,C#,Exception,我试图从类内部更新richtextbox,而不是从表单。下面是我的代码:我将表单作为参数传递给客户机类的构造函数 public partial class Form1 : Form { public void AppendText(string s) { richtextbox_server_activities.AppendText(s + "\n"); } public Form1() { clien

我试图从类内部更新richtextbox,而不是从表单。下面是我的代码:我将表单作为参数传递给客户机类的构造函数

 public partial class Form1 : Form
 {
     public void AppendText(string s)
     {
         richtextbox_server_activities.AppendText(s + "\n");
     }

     public Form1()
     {
         client = new Client(e.Accepted,e.user,this);
     }

   //rest of the code of the form
 }
以及类“Client”中的函数,我尝试在其中更新gui:

private Form1 form;

public Client(string username, Form1 form)
{
    this.form = form;
    _baseSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    this.username = username;
}

private void process()
{
    int id = pr.ReadInt32();
    long index = pr.ReadInt64();
    int size = pr.ReadInt32();
    byte[] buffer = pr.ReadBytes(size);

    TransferQueue queue = _transfers[id];

    queue.Write(buffer, index);

    queue.Progress = (int)((queue.Transferred * 100) / queue.Length);
    if (queue.LastProgress < queue.Progress)
    {
        queue.LastProgress = queue.Progress;

        if (ProgressChanged != null)
        {
             ProgressChanged(this, queue);
        }

        if (queue.Progress == 100)
        {   //HERE IS WHERE I GET EXCEPTION
            this.form.AppendText("Client " + this.username + " has completed uploading the file " + queue.Filename + ".");
            queue.Close();

             if (Complete != null)
             {
                 Complete(this, queue);
             }
         }
}
私有表单1表单;
公共客户端(字符串用户名,Form1表单)
{
this.form=形式;
_baseSocket=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
this.username=用户名;
}
私有无效进程()
{
int id=pr.ReadInt32();
长索引=pr.ReadInt64();
int size=pr.ReadInt32();
byte[]buffer=pr.ReadBytes(大小);
TransferQueue队列=_传输[id];
写入(缓冲区、索引);
queue.Progress=(int)((queue.transfer*100)/queue.Length);
if(queue.LastProgress
但是我得到一个错误,说跨线程操作无效:从创建控件的线程以外的线程访问控件。我查看了类似的问题,但仍然得到这个错误。有人看到问题了吗


谢谢

问题是您正在使用
客户端
类中的另一个线程访问
Form1
控件,您需要调用到正确的线程上

例如:

public void AppendText(string s)
{
    Invoke((Action)delegate { richTextBox1.AppendText(s + "\n"); });
}
 public Form1()
 {
     client = new Client(e.Accepted,e.user,AppendText);
 }



public class Client
{
    private Action<string> _callback;

    public Client(string username, Action<string> callback)
    {
        _callback = callback;
    }


    private void Process()
    {
        .......

        _callback("Client " + this.username + " has completed uploading the file " + queue.Filename + ".");
    }
}
委托
传递到
客户端
而不是整个表单可能是更好的选择

例如:

public void AppendText(string s)
{
    Invoke((Action)delegate { richTextBox1.AppendText(s + "\n"); });
}
 public Form1()
 {
     client = new Client(e.Accepted,e.user,AppendText);
 }



public class Client
{
    private Action<string> _callback;

    public Client(string username, Action<string> callback)
    {
        _callback = callback;
    }


    private void Process()
    {
        .......

        _callback("Client " + this.username + " has completed uploading the file " + queue.Filename + ".");
    }
}
public Form1()
{
客户端=新客户端(e.Accepted,e.user,AppendText);
}
公共类客户端
{
私人行动;
公共客户端(字符串用户名、操作回调)
{
_回调=回调;
}
私有无效进程()
{
.......
_回调(“客户端”+this.username+“已完成上传文件”+queue.Filename+”);
}
}

取决于谁(哪个线程)正在调用
process
方法。@UweKeim客户端类中的一个函数调用该过程函数只需确保主UI线程正在更新控件。@panpa它不取决于哪个类中的哪个方法调用该方法。它取决于哪个线程调用它,正如Uwe所说的那样。@panpa现在搜索它。对于或者这个关于在另一个线程中更新UI的异常。谢谢你的回答,我用了另一种方法,它成功了。我遵循了这个链接的说明:如果你使用它,它的作用与传递委托解决方案基本相同,但它会为你调用(它在创建同步上下文时调用任何对象)。我假设.NET3.5是它的winforms,但是如果.NET4.5是,那么这是一个更好的选项,
IProgress
通过NuGet包可用于4.0