Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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# 为什么我不能递归调用Worker\u DoWork函数?_C#_Sockets_Networking_Tcp - Fatal编程技术网

C# 为什么我不能递归调用Worker\u DoWork函数?

C# 为什么我不能递归调用Worker\u DoWork函数?,c#,sockets,networking,tcp,C#,Sockets,Networking,Tcp,我在c#中使用Sytem.Net.Sockets使用tcp服务器和客户端。我的工作函数如下 private void Worker_DoWork(object sender, DoWorkEventArgs e) { byte[] buffer = new byte[1]; socket.Receive(buffer); chatTextBox.Text = buffer[0].ToString(); } 我

我在c#中使用Sytem.Net.Sockets使用tcp服务器和客户端。我的工作函数如下

   private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        byte[] buffer = new byte[1];
        socket.Receive(buffer);
        chatTextBox.Text = buffer[0].ToString();        
    }
我在服务器创建之后调用它,一旦它从客户端接收到消息,它就会将消息写入屏幕并停止。我的问题是我希望它在最后再次调用自己,以便它等待另一条消息显示。如果我只添加worker.RunWorkerAsync();在底部,它不工作,但是如果我只是从另一个按钮调用它,它就会工作,并接收和写入消息。

BackgroundWorker“缠绕”一条线程,并帮助您处理所有管道。这是一种非常过时的多任务处理方法,您不应该再在生产代码中使用它。然而,它也是我所知道的最好的多任务“训练轮”

你的基本方法有缺陷。BGW不允许这样做,实际上只是帮助你学习你需要学习的东西。代码中的错误列表:

  • 您直接在DoWork中访问GUI元素。不要那样做。仅在ReportProgress和RunWorker completed事件中写入UI。这是一个,这是由德BGW的设计帮助
  • 您正在尝试在线程完成之前重新启动它。如果您想重新启动它,RunWorkerCompleted将是正确的位置
  • 然而,更明智的做法是,BackgroundWorker的核心是一个半无限循环。在取消之前一直运行的东西。通常情况下,在报告的同时分发信息不是一个好主意,但在这种情况下,这是我最好的主意
我唯一能给你的是我以前的BGW示例代码:

#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
    if (!bgwPrim.IsBusy)
    {
        //Prepare ProgressBar and Textbox
        int temp = (int)nudPrim.Value;
        pgbPrim.Maximum = temp;
        tbPrim.Text = "";

        //Start processing
        bgwPrim.RunWorkerAsync(temp);
    }
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
    if (bgwPrim.IsBusy)
    {
        bgwPrim.CancelAsync();
    }
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
    int highestToCheck = (int)e.Argument;
    //Get a reference to the BackgroundWorker running this code
    //for Progress Updates and Cancelation checking
    BackgroundWorker thisWorker = (BackgroundWorker)sender;

    //Create the list that stores the results and is returned by DoWork
    List<int> Primes = new List<int>();


    //Check all uneven numbers between 1 and whatever the user choose as upper limit
    for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
    {
        //Report progress
        thisWorker.ReportProgress(PrimeCandidate);
        bool isNoPrime = false;

        //Check if the Cancelation was requested during the last loop
        if (thisWorker.CancellationPending)
        {
            //Tell the Backgroundworker you are canceling and exit the for-loop
            e.Cancel = true;
            break;
        }

        //Determin if this is a Prime Number
        for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
        {
            if (PrimeCandidate % j == 0)
                isNoPrime = true;
        }

        if (!isNoPrime)
            Primes.Add(PrimeCandidate);
    }

    //Tell the progress bar you are finished
    thisWorker.ReportProgress(highestToCheck);

    //Save Return Value
    e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    pgbPrim.Value = pgbPrim.Maximum;
    this.Refresh();

    if (!e.Cancelled && e.Error == null)
    {
        //Show the Result
        int[] Primes = (int[])e.Result;

        StringBuilder sbOutput = new StringBuilder();

        foreach (int Prim in Primes)
        {
            sbOutput.Append(Prim.ToString() + Environment.NewLine);
        }

        tbPrim.Text = sbOutput.ToString();
    }
    else 
    {
        tbPrim.Text = "Operation canceled by user or Exception";
    }
}
#endregion
#区域素数
私有无效btnPrimStart\单击(对象发送者,事件参数e)
{
如果(!bgwPrim.IsBusy)
{
//准备进度条和文本框
int temp=(int)nudPrim.Value;
pgbPrim.最大值=温度;
tbPrim.Text=“”;
//开始处理
bgwPrim.RunWorkerAsync(临时);
}
}
私有无效btnprimmcancel\u单击(对象发送者,事件参数e)
{
如果(bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
私有void bgwPrim_DoWork(对象发送方,DoWorkEventArgs e)
{
int highestToCheck=(int)e.参数;
//获取运行此代码的BackgroundWorker的引用
//用于进度更新和取消检查
BackgroundWorker thisWorker=(BackgroundWorker)发件人;
//创建存储结果并由DoWork返回的列表
列表素数=新列表();
//检查1和用户选择的任何上限之间的所有不均匀数
对于(int PrimeCandidate=1;PrimeCandidate
添加RunWorkerComplete的第二个建议正是我想要的!我知道这是非常糟糕的编码,但我只是想了解这个过程到底是如何工作的,这对我很有帮助。你说后台工作是一个过时的东西,我应该用什么来代替它来运行我的多任务?任何链接总是感激!只是做一个简单的客户端/服务器tcp聊天应用程序@Rainflow901对于初学者来说,BGW是理想的选择。通过它的限制和规则,它基本上迫使你进入正确的模式。当前的“东西”是异步机制。一种不用一路依赖线程就能完成多任务的方法。通常,线程只应在两种情况下使用:a)工作受CPU限制。但这种情况很少见。b) 大型服务器。这些都是线程池。线程带来的隔离会有很大帮助。