में एकाधिक घटनाओं का इंतजार है मैं producer/consumer pattern का उपयोग कर डेटा लिंक परत लागू कर रहा हूं। डेटा लिंक परत के पास तार (ईथरनेट, आरएस -223 ...) पर डेटा लिंक प्रोटोकॉल को संवाद करने के लिए अपना स्वयं का धागा और राज्य मशीन है। भौतिक परत के लिए इंटरफ़ेस को System.IO.Stream के रूप में दर्शाया गया है। एक और धागा डेटा लिंक ऑब्जेक्ट से संदेश लिखता है और पढ़ता है।सी # निर्माता/उपभोक्ता
- एक बाइट प्राप्त होता है
- एक संदेश नेटवर्क धागा
- रखें जिंदा टाइमर से उपलब्ध है:
डेटा लिंक वस्तु एक निष्क्रिय अवस्था है कि चार शर्तों में से एक के लिए इंतज़ार करना होगा है
- समाप्त हो गया है सभी संचार नेटवर्क परत
मैं एक कठिन समय figu आ रही द्वारा रद्द कर दिया गया एक पढ़ने/लिखने के धागे में संचार को विभाजित किए बिना ऐसा करने का सबसे अच्छा तरीका रिंग करें (जिससे जटिलता में काफी वृद्धि हो)। यहाँ मैं कैसे 4 में से 3 प्राप्त कर सकते हैं:
// Read a byte from 'stream'. Timeout after 10 sec. Monitor the cancellation token.
stream.ReadTimeout = 10000;
await stream.ReadAsync(buf, 0, 1, cts.Token);
या
BlockingCollection<byte[]> SendQueue = new ...;
...
// Check for a message from network layer. Timeout after 10 seconds.
// Monitor cancellation token.
SendQueue.TryTake(out msg, 10000, cts.Token);
मैं सभी चार स्थितियों के लिए इंतजार कर रहे धागा ब्लॉक करने के लिए, क्या करना चाहिए? सभी सिफारिशों का स्वागत है। मैं किसी भी वास्तुकला या डेटा संरचनाओं पर सेट नहीं हूँ।
संपादित करें: ******** सभी की सहायता के लिए धन्यवाद। यहां मेरा समाधान है ********
सबसे पहले मुझे नहीं लगता कि निर्माता/उपभोक्ता कतार का एक असीमित कार्यान्वयन था। तो मैंने this stackoverflow post के समान कुछ लागू किया।
मुझे उपभोक्ता धागे को रोकने और क्रमशः similar to this article को मध्यवर्ती कार्यों को रद्द करने के लिए बाहरी और आंतरिक रद्दीकरण स्रोत की आवश्यकता थी।
byte[] buf = new byte[1];
using (CancellationTokenSource internalTokenSource = new CancellationTokenSource())
{
CancellationToken internalToken = internalTokenSource.Token;
CancellationToken stopToken = stopTokenSource.Token;
using (CancellationTokenSource linkedCts =
CancellationTokenSource.CreateLinkedTokenSource(stopToken, internalToken))
{
CancellationToken ct = linkedCts.Token;
Task<int> readTask = m_stream.ReadAsync(buf, 0, 1, ct);
Task<byte[]> msgTask = m_sendQueue.DequeueAsync(ct);
Task keepAliveTask = Task.Delay(m_keepAliveTime, ct);
// Wait for at least one task to complete
await Task.WhenAny(readTask, msgTask, keepAliveTask);
// Next cancel the other tasks
internalTokenSource.Cancel();
try {
await Task.WhenAll(readTask, msgTask, keepAliveTask);
} catch (OperationCanceledException e) {
if (e.CancellationToken == stopToken)
throw;
}
if (msgTask.IsCompleted)
// Send the network layer message
else if (readTask.IsCompleted)
// Process the byte from the physical layer
else
Contract.Assert(keepAliveTask.IsCompleted);
// Send a keep alive message
}
}
['कार्य का इंतजार करें। जब कोई (...)'] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenany%28v=vs.110%29.aspx) मदद हो सकती है। –