2012-07-02 8 views
5

कार्यात्मक रूप से ListView से जुड़े शब्दों की एक लंबी सूची है। शब्दों की सूची फ़िल्टर करने के लिए वर्णों के लिए टेक्स्टबॉक्स का प्रयोग करें।किसी भी मौजूदा समानांतर को कैसे रद्द करें। प्रत्येक के लिए और ताजा शुरू करें

किसी भी नए चार को किसी भी प्रोसेसिंग पृष्ठभूमि फ़िल्टर को रद्द करने की आवश्यकता के साथ। फिर एक ताजा पृष्ठभूमि समानांतर फ़िल्टर शुरू करने के लिए 1 सेकंड (डिस्पैचर टाइमर) प्रतीक्षा करें।

यह बैकग्राउंडवर्कर का उपयोग कर काम कर रहा है लेकिन रद्द-किसी भी प्रसंस्करण भाग को समांतर में अनुवाद नहीं कर सकता है। मूल रूप से "अगर (BackgroundWorkerFTSfilter.IsBusy) पृष्ठभूमि WorkerFTSfilter.CancelAsync();" समान्तर में।
यदि मैं इस गलत के बारे में जा रहा हूं तो कृपया मुझे बताएं।

private List<FTSword> fTSwordsFiltered = new List<FTSword>(); 
CancellationTokenSource ftsCts = new CancellationTokenSource(); 
ParallelOptions ftspo = new ParallelOptions(); 
// in ctor ftspo.CancellationToken = ftsCts.Token; 

public List<FTSword> FTSwordsFiltered // ListView bound to 
{ 
    get { return fTSwordsFiltered; } 
    set 
    { 
     if (fTSwordsFiltered == value) return; 
     fTSwordsFiltered = value; 
     NotifyPropertyChanged("FTSwordsFiltered"); 
    } 
} 
public string FTSwordFilter   // TextBox bound to 
{ 
    get { return fTSwordFilter; } 
    set 
    { 
     if (value == fTSwordFilter) return; 

     fTSwordFilter = value; 
     NotifyPropertyChanged("FTSwordFilter"); 

     // cancel any filter currently processing 
     ftsCts.Cancel(); // fts filter    
     // with BackgroundWorker this was able to cancel    
     // if (backgroundWorkerFTSfilter.IsBusy) backgroundWorkerFTSfilter.CancelAsync(); 

     dispatcherTimerFTSfilter.Stop(); 
     // wait 1 second and apply filter in background 
     dispatcherTimerFTSfilter.Start(); 
    } 
} 
private void dispatcherTimerFTSfilter_Tick(object sender, EventArgs e) 
{ 
    dispatcherTimerFTSfilter.Stop(); 
    List<FTSword> ftsWords = new List<FTSword>(); 
    //ftsCts = new CancellationTokenSource(); with these two it never cancels 
    //ftspo.CancellationToken = ftsCts.Token; 
    if (!(string.IsNullOrEmpty(FTSwordFilter))) 
    { 
     Task.Factory.StartNew(() => 
     { 

      try 
      { 
       Parallel.ForEach(FTSwords, ftspo, ftsw => 
       { 
        if (ftsw.WordStem.StartsWith(FTSwordFilter)) 
        { 
         ftsWords.Add(ftsw); 
        } 
        ftspo.CancellationToken.ThrowIfCancellationRequested(); 
       }); 
       Thread.Sleep(1000); // so the next key stoke has time 
       FTSwordsFiltered = (List<FTSword>)ftsWords; 
      } 
      catch (OperationCanceledException ei) 
      { 
       // problem is that it is always cancelled from the cancel request before DispatchTimer 
       Debug.WriteLine(ei.Message); 
      } 
      Debug.WriteLine(ftsWords.Count.ToString() + "parallel "); 
     });   
    } 
} 

Irman से जवाब मुझे इस

if (!(string.IsNullOrEmpty(FTSwordFilter))) 
    { 
     string startWorkFilter = FTSwordFilter; 
     Task.Factory.StartNew(() => 
     { 
      try 
      { 
       fTSwordsFilteredCancel = false; 
       Parallel.ForEach(FTSwords, ftspo, (ftsw, loopstate) => 
       { 
        if (ftsw.WordStem.StartsWith(startWorkFilter)) 
        { 
         ftsWords.Add(ftsw); 
        } 
        // Thread.Sleep(1); 
        if (fTSwordsFilteredCancel) 
        { 
         loopstate.Break(); 
        } 
       }); 
       Debug.WriteLine("fTSwordsFilteredCancel " + fTSwordsFilteredCancel.ToString()); 
       FTSwordsFiltered = (List<FTSword>)ftsWords; 
       Debug.WriteLine(ftsWords.Count.ToString() + " parallel " + startWorkFilter);      
      } 
      catch (OperationCanceledException ei) 
      { 
       Debug.WriteLine(ei.Message); 
      } 
     }); 
    } 

उत्तर के लिए बहुत आभारी करने के लिए नेतृत्व मैं और कुछ लंबे समय तक चल रहे कार्यों या उससे अधिक समय सूची के लिए इस का उपयोग करेगा लेकिन इस तरह के शानदार प्रदर्शन रहा करने के लिए इस ले जाया मिला प्राप्त करें (अभी भी 1 सेकंड देरी के साथ)। एक छोटी स्मृति पदचिह्न में परिणाम। 800,000 के खिलाफ यह 1/10 सेकंड से भी कम समय में चलता है।

public IEnumerable<FTSword> FTSwordsFiltered 
{ 
    get 
    { 
     if(string.IsNullOrEmpty(FTSwordFilter) || FTSwordFilter == "*") return FTSwords; 
     return FTSwords.AsParallel().Where(ftsWrd => ftsWrd.WordStem.StartsWith(FTSwordFilter)); 
    } 

उत्तर

5

समांतर। फॉरएच समानांतर लूपस्टेट ऑब्जेक्ट के साथ आता है। आप लूप को तोड़ने के लिए इस ऑब्जेक्ट का उपयोग कर सकते हैं।

आप या तो अपनी आवश्यकताओं के आधार पर loopState.Break() या loopState.Stop() का उपयोग कर सकते हैं।

इसे जांचें।

http://msdn.microsoft.com/en-us/library/dd991486.aspx

+0

कृपया जांच करें कि मैं क्या लगता है loopState.Break के सही उपयोग है() से पहले जवाब के रूप में मैं निशान। (समानांतर संस्करण इतना तेज़ था कि मुझे समांतर में नींद डालना पड़ा था। यहां तक ​​कि रद्द करने का समय भी है) – Paparazzi

+0

यह अच्छा लग रहा है। यदि आप रद्दीकरण टोकन का उपयोग नहीं करना चाहते हैं, तो आप समानांतर में पारित समांतर विकल्प ऑब्जेक्ट को हटा सकते हैं। प्रत्येक कॉल के लिए। बीटीडब्ल्यू - समांतर विकल्प का उपयोग इस कॉल को चलाने के लिए प्रयुक्त प्रोसेसर की संख्या को सीमित करने के लिए भी किया जाता है। –

+0

सीटीआर में मैंने ftspo.MaxDegreeOfParallelism = System.Environment.ProcessorCount सेट किया है; चीजों को बाधित रखने के लिए। – Paparazzi

संबंधित मुद्दे