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