在任务中使用异步套接字

本文关键字:异步 套接字 任务 | 更新日期: 2023-09-27 18:24:38

我有一个应用程序,它正在使用.net 4.0中的Tasks处理FIFO队列中的项目。

我是TPL和.net中Tasks的新手,想知道是否有一个简单的解决方案:

Task中的Action委托被分配给一个在异步套接字上发送和接收数据的方法。我遇到的问题是任务"过早"结束。如何告诉Task等待所有通信完成后再处理队列中的下一个项目?

一种解决方案是切换到使用同步套接字,但我希望有一种使用异步套接字的方法。

编辑添加了一些代码:

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...
    }
}

问题是,当DoSomeWork()方法完成时,Task就结束了(我理解为什么),有没有一种方法可以通过CancellationTokenSource对象手动告诉Task结束?

在任务中使用异步套接字

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

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();
}

这只是使用AutoResetEvent的一个例子——您可能希望对其进行改进以满足您的需求。