Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#_Multithreading_Tcp_Backgroundworker_Client Side - Fatal编程技术网

C# 取消正在从网络流中连续读取的后台工作进程

C# 取消正在从网络流中连续读取的后台工作进程,c#,multithreading,tcp,backgroundworker,client-side,C#,Multithreading,Tcp,Backgroundworker,Client Side,我有一个TCP服务器在运行,它定期吐出2字节的消息 我正在尝试创建一个客户端表单,它连接到服务器并不断地从流中读取数据,直到我单击表单上的断开连接按钮 到目前为止,客户端工作正常,只是我无法断开连接。我将CancellationPending设置为true,但在dowork方法有机会设置e.Cancel之前,它似乎重置回false 我还确信,必须有一种更可接受的方式来持续读取流并写入表单——目前,我正在Worker Completed方法中调用RunWorkerAsync来实现循环 pr

我有一个TCP服务器在运行,它定期吐出2字节的消息

我正在尝试创建一个客户端表单,它连接到服务器并不断地从流中读取数据,直到我单击表单上的断开连接按钮

到目前为止,客户端工作正常,只是我无法断开连接。我将CancellationPending设置为true,但在dowork方法有机会设置e.Cancel之前,它似乎重置回false

我还确信,必须有一种更可接受的方式来持续读取流并写入表单——目前,我正在Worker Completed方法中调用RunWorkerAsync来实现循环

    private void Disconnect()
    {
        commsWorker1.CancelAsync();
    }

    private void ReadFromStream()
    {
        try
        {
            commsWorker1.RunWorkerAsync();
        }
        catch (Exception ex)
        {
            writeToBox("Error: " + ex.Message);
        }
    }

    //background worker dowork method
    private void BackGroundGetServerData(object sender, DoWorkEventArgs e)
    {
        if (true == commsWorker1.CancellationPending)
        {
            e.Cancel = true;
        }
        else
        {
            Byte[] dataArray = new Byte[2];
            try
            {
                _DataStream.Read(dataArray, 0, 2);
                String reply = System.Text.Encoding.ASCII.GetString(dataArray);
                e.Result = reply;
            }
            catch (Exception ex)
            {
            }
        }
    }

    //background worker workercompleted method
    private void BackGroundDisplayMessages(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            //close connection here
        }
        else
        {
            writeToBox((String)e.Result);
            commsWorker1.RunWorkerAsync();
        }

    }
}

}

您不能在后台工作程序方法内部循环吗

private void BackGroundGetServerData(object sender, DoWorkEventArgs e)
{
    while(true)
    {
        Byte[] dataArray = new Byte[2];
        try
        {
            _DataStream.Read(dataArray, 0, 2);
            String reply = System.Text.Encoding.ASCII.GetString(dataArray);
            e.Result = reply;
        }
        catch (Exception ex)
        {
            return;
        }
    }
}
然后在断开连接后,只需关闭插座。这将导致
异常
在while循环中抛出,您可以通过
catch
块优雅地退出

编辑
:然后在读取每条消息后,您可以从循环中更新GUI。确保您正在更新的控件的句柄可用(假设它被称为
):


在这种情况下,需要使用
BeginInvoke
,因为您试图从另一个线程更新GUI,这是不允许的。此方法将更新转发到GUI线程。

似乎您正在worker complete方法中调用RunWorkerAsync(),并重置CancellationPending属性。我认为您可以通过在Disconnect()方法中添加一些disconnectFlag=true来解决这个问题;在WorkerComplete方法中,您应该添加:

if (e.Cancelled || disconnectFlag)
    {
        disconnectFlag = false;
        //close connection here
    } else ...

在这种情况下如何调用BackGroundDisplayMessages?如果我在DoWork方法中循环,我想,WorkerCompleted方法将永远不会被调用,因此从流中读取的值将永远不会被显示?感谢Tudor,非常感谢,我采用了您的方法,它完成了工作!您是否将WorkerSupportsScanCellation设置为true?抱歉,是的,应该注意,WorkerSupportsScanCellation和WorkerSupportsProgress都为true。
if (e.Cancelled || disconnectFlag)
    {
        disconnectFlag = false;
        //close connection here
    } else ...