Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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#_.net_Multithreading_Task Parallel Library_Task - Fatal编程技术网

C# 在任务中使用异步套接字

C# 在任务中使用异步套接字,c#,.net,multithreading,task-parallel-library,task,C#,.net,Multithreading,Task Parallel Library,Task,我有一个应用程序正在使用.NET4.0中的任务处理FIFO队列中的项目 我不熟悉.net中的TPL和任务,想知道是否有一个简单的解决方案来解决我的问题: 任务中的操作委托被分配给在异步套接字上发送和接收数据的方法。我面临的问题是任务“过早”结束。如何告诉任务在处理队列中的下一项之前等待所有通信完成 一种解决方案是切换到使用同步套接字,但我希望有一种方法可以使用异步套接字实现这一点 编辑 添加了一些代码: class Program { private BlockingCollection

我有一个应用程序正在使用.NET4.0中的任务处理FIFO队列中的项目

我不熟悉.net中的TPL和任务,想知道是否有一个简单的解决方案来解决我的问题:

任务中的操作委托被分配给在异步套接字上发送和接收数据的方法。我面临的问题是任务“过早”结束。如何告诉任务在处理队列中的下一项之前等待所有通信完成

一种解决方案是切换到使用同步套接字,但我希望有一种方法可以使用异步套接字实现这一点

编辑 添加了一些代码:

class Program
{
    private BlockingCollection<string> myQueue;
    private CancellationTokenSource cancellationSignalForConsumeTask;
    private CancellationTokenSource cancellationSignalForProcessCommandTask;
    private AsyncSocket mySocket;

    public void Main(string[] args)
   {
       mySocket = new mySocket();
       myscoket.ReceiveData += mySocket_ReceiveData;

       cancellationSignalForConsumeTask = new CancellationTokenSource();
       Task listenerTask = Task.Factory.StartNew((obj) => Consume(),
                                                          cancellationSignalForConsumeTask.Token,
                                                          TaskCreationOptions.LongRunning);

        while (true)
        {}
   }

    private void Consume()
    {
       while (!myQueue.IsCompleted )
            {
                string _item = myQueue.Take();

                cancellationSignalForProcessCommandTask = new CancellationTokenSource();
                Task t = new Task(() => 
                    {
                        cancellationSignalForProcessCommandTask.Token.ThrowIfCancellationRequested();
                        DoSomeWork(_item);
                    }, cancellationSignalForProcessCommandTask.Token, TaskCreationOptions.LongRunning);

                t.Start();
                t.Wait();
            }
    }

    private void DoSomeWork(string _item)
    {
       mySocket.SendData("Data to server that could take a long time to process")
    }

    private void mySocket_ReceiveData(string dataFromServer)
    {
        string returnMessage = dataFromServer;

        //I want the Task to end here...

    }
}
类程序
{
私有阻塞收集myQueue;
private CancellationTokenSource cancellationSignalForConsumeTask;
private CancellationTokenSource cancellationSignalForProcessCommandTask;
私有异步套接字mySocket;
公共void Main(字符串[]参数)
{
mySocket=新的mySocket();
myscoket.ReceiveData+=mySocket\u ReceiveData;
cancellationSignalForConsumeTask=新的CancellationTokenSource();
Task listenerTask=Task.Factory.StartNew((obj)=>Consume(),
cancellationSignalForConsumeTask.Token,
TaskCreationOptions.LongRunning);
while(true)
{}
}
私有void消费()
{
而(!myQueue.IsCompleted)
{
字符串_item=myQueue.Take();
cancellationSignalForProcessCommandTask=新的CancellationTokenSource();
任务t=新任务(()=>
{
ProcessCommandTask.Token.ThrowIfCancellationRequested()的取消信号;
DoSomeWork(_项);
},取消ProcessCommandTask.Token的信号,TaskCreationOptions.LongRunning);
t、 Start();
t、 等待();
}
}
专用无效文件系统(字符串_项)
{
SendData(“发送到服务器的数据可能需要很长时间才能处理”)
}
private void mySocket_ReceiveData(来自服务器的字符串数据)
{
字符串returnMessage=dataFromServer;
//我希望任务在这里结束。。。
}
}

问题是任务在
DoSomeWork()
方法完成时结束(我理解原因),是否有办法通过
CancellationTokenSource
对象手动告诉任务结束可能?

如果我理解正确,您希望等待任务接收数据,但您当前正在等待发送数据的任务。一种方法是使用如下构造:


这只是使用
AutoResetEvent
的一个示例-您可能希望对其进行优化以满足您的需要。

可能是根线程/任务上的等待()。你能展示你目前拥有的代码吗?发布你目前拥有的代码。什么是
AsyncSocket
?如果
SendData()
是异步的,那么您可能需要等待它。请注意,同步线程时应小心。例如,如果
DoSomeWork
发送两个单独的数据字符串,则您希望仅在接收到所有数据后调用
Set
,否则,第二个任务将在第一个任务完成之前启动。
private AutoResetEvent autoResetEvent = new AutoResetEvent(false);

private void Consume()
{
   while (!myQueue.IsCompleted )
        {
            string _item = myQueue.Take();

            cancellationSignalForProcessCommandTask = new CancellationTokenSource();
            Task t = new Task(() => 
                {
                    cancellationSignalForProcessCommandTask.Token.ThrowIfCancellationRequested();
                    DoSomeWork(_item);
                }, cancellationSignalForProcessCommandTask.Token, TaskCreationOptions.LongRunning);

            t.Start();

            // Wait for data to be received.
            // This line will block until autoResetEvent.Set() is called.
            autoResetEvent.WaitOne();
        }
}

private void mySocket_ReceiveData(string dataFromServer)
{
    string returnMessage = dataFromServer;

   // Notify other threads that data was received and that processing can continue.
   autoResetEvent.Set();
}