2012-09-28 13 views
8

का उपयोग करते हुए थोड़ी देर के अंतराल को तोड़ें मेरे पास विंडोज़ सेवा में थोड़ी देर लूप है जो कुछ x बार के लिए चलता है और कुछ फ़ाइल से उन्हें पढ़ने के बाद एक्स फोन कॉल को उत्तेजित करता है। अब अगर मैं एक यूजर इंटरफेस बनाना चाहता हूं जो फोन कॉल को रोकने का विकल्प देता है यानी पूरा होने से पहले भी लूप को तोड़ दें। मैं यह कैसे करूँगा?बाहरी ईवेंट

मान लीजिए कि मेरे पास एक कार्य है।

DialCalls(x) 
{ 
    for(int i= 0 ; i<x ; i++) 
    { 
    // Initiate call 
    } 
} 

2,3 DialCalls अलग धागे में एक ही समय में चल रहा है के रूप में मैं आवेदन में सूत्रण के रूप में अच्छी तरह से किया है कार्यों वहाँ हो सकता है। तो मूल रूप से किसी वेबपृष्ठ से लूप को तोड़ने का सबसे अच्छा तरीका क्या है।

+1

'अस्थिर' का सुझाव देने वाले लोगों के लिए: http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are- अलग-part-three.aspx –

उत्तर

6

task रद्द (.net 4 में नए) का उपयोग करना:

[Fact] 
public void StartAndCancel() 
{ 
    var cancellationTokenSource = new CancellationTokenSource(); 
    var token = cancellationTokenSource.Token; 
    var tasks = Enumerable.Repeat(0, 2) 
          .Select(i => Task.Run(() => Dial(token), token)) 
          .ToArray(); // start dialing on two threads 
    Thread.Sleep(200); // give the tasks time to start 
    cancellationTokenSource.Cancel(); 
    Assert.Throws<AggregateException>(() => Task.WaitAll(tasks)); 
    Assert.True(tasks.All(t => t.Status == TaskStatus.Canceled)); 
} 

public void Dial(CancellationToken token) 
{ 
    while (true) 
    { 
     token.ThrowIfCancellationRequested(); 
     Console.WriteLine("Called from thread {0}", Thread.CurrentThread.ManagedThreadId); 
     Thread.Sleep(50); 
    } 
} 

http://blogs.msdn.com/b/csharpfaq/archive/2010/07/19/parallel-programming-task-cancellation.aspx कार्य अपवाद निगल इसलिए कुछ सफाई करने के लिए, हो सकता है IDisposable के रूप में है? About task exceptions

+1

यह एक अच्छा जवाब है (इसलिए +1), लेकिन आप लेख से कुछ प्रासंगिक स्निपेट को शामिल करके इसे बेहतर बना सकते हैं। –

4

बाहरी घटना की स्थिति को मतदान करने के लिए आप अपने लूप के अंदर एक if-statement लिख सकते हैं।

bool break_out = false;

और अपने बाहरी घटना में, आप सत्य पर break_out ध्वज सेट:

break_out = true;

अब आप अपने पाश में,

उदाहरण के लिए, यदि आप एक झंडा हो सकता था आप हो सकते हैं:

DialCalls(x) 
{ 
    for(int i= 0 ; i<x ; i++) 
    { 
    // Initiate call 

    if (break_out) { 
     break; 
    } 
    } 
} 
3

एक घटना का समर्थन रद्द बनाएँ:

public event EventHandler<CancelEventArgs> Call; 

ग्राहक मौजूद है और यह रद्द करते हैं, तो फोन नहीं है:

while (true) 
{ 
    var e = new System.ComponentModel.CancelEventArgs(); 
    if (Call != null) 
    { 
     Call(this, e); 
    } 
    if (!e.Cancel) 
    { 
     // Initiate call 
    } 
    else 
    { 
     break; 
    } 
} 
0

जब तोड़ने के लिए एक चर कह का उपयोग करके।

private bool _cancel; 

void DialCalls(...) 
{ 
    for (int i=0; i<x; i++) 
    { 
     ... 
     if (_cancel) break; 
     .... 
    } 
} 

private void SomeEventHandler(object sender, EventArgs e) 
{ 
    _cancel = true; 
} 

या

for (int i=0; i<x && !_cancel; i++) 
0

एक वैश्विक चर जो अस्थिर

public static volatile bool stop;  
stop=False; 

DialCalls(x) 
{ 
    for(int i= 0 ; i<x && !stop ; i++) 
    { 
    // Initiate call 
    } 
} 

On Button Click => stop =True; 
0

सेवा है कि एक संदेश है कि एक वैश्विक/स्थिर बूलियन टॉगल स्वीकार पर एक endpoint लागू है (या कुछ अन्य है) परिवर्तनीय, और DialCalls के अंदर लूप है प्रत्येक पुनरावृत्ति की शुरुआत में कहा वैरिएबल जांचें। यह वर्तमान में प्रगति पर किसी भी फोन कॉल को बाधित नहीं करेगा, लेकिन मैं शर्त लगा रहा हूं कि आप कॉल के बीच में लटकने की सेवा नहीं चाहते हैं, बस अगले नंबर पर न जाएं। यह सभी धागे के लिए भी बाधित होगा; बस सुनिश्चित करें कि वेरिएबल स्वयं थ्रेड-सुरक्षित है (उदाहरण के लिए, volatile कीवर्ड का उपयोग करें)।

1
while (!_shouldStop) { /* work in progress */ } 

और Stop() विधि है जो एक ही कार्यकर्ता वर्ग bool चर के रूप में सही सेट किया जाना चाहिए पर होना चाहिए में।

इसके अलावा, यदि कोई वेटर्स (जैसे AutoResetEvent) है तो वे .Set(); होना चाहिए।