c# - The synchronous behavior of The Multi-Threaded Method -


after long work hours on this, couldn't success multi-threading method. appreciate help.

i have listview , in first column has urls need later in other methods. seconds column result.

i'm creating 2 arraylists urls , sending them(urls arraylist) method, in method, httpwebrequest, i'm getting page title each url.

so problem when try fire 5 threads, works :

(u : url, r: result)

u1 = r1 ( so, must u1's result r1..)

but i'm getting :

u1 = r1, u2 = r1, u3(or4) = r1, u4 = r1, u5=r2(or3,4)

but expecting : u1=r1, u2=r2, u3=r3, u4=r4...

for better explanation please check the pictures below

then tried use lock keyword private object lost multi-threading.it works excepted 1 one. not fire 5 different threads @ same time , waits finishing thread 1 move next thread.

///main class///

/* store of created threads. */ arraylist _threads = new arraylist(); /* store of filedownloader objects. */ arraylist _instances = new arraylist(); private int _activedownloadcount = 0; object _lockobject = new object(); 

the button :

_instances = new arraylist(); _threads = new arraylist(); _activedownloadcount = 0;  filedownloader download = null; foreach (listviewitem item in listviewurl.items) {                  item.subitems[9].text = "not started";              download = new filedownloader(item.subitems[0].text);                    item.tag = download;                     try     {        threadstart tsdelegate = new threadstart(download.download);        download.downloadstarting += new filedownloader._deldownloadstarting(download_downloadstarting);        download.downloadcompleted += new filedownloader._deldownloadcompleted(download_downloadcompleted);         thread t = new thread(tsdelegate);        t.name = item.subitems[0].text;        _threads.add(t);        _instances.add(download);      }     catch     {          item.subitems[9].text = "error";     } } startdownload(); 

startdownload method :

int j = 0; int limit = int.parse(numthreadsearch.text); int icount = 0; lock (_lockobject) {     icount = _instances.count; } if (icount != 0) {     foreach (thread thread in _threads)     {         filedownloader file = ((filedownloader)_instances[j]);         if (file._isstarted == false)         {             lock (_lockobject)             {                 thread.start();                  console.writeline(_activedownloadcount);                 _activedownloadcount++;             }         }         if (_activedownloadcount == limit)         {             break;         }         j++;     } } else {     /* if files have downloaded, here. } 

when method completed :

 void download_downloadcompleted(filedownloader thread, bool issuccess)         {              lock (_lockobject)             {                 _activedownloadcount--;              }              pagerankreturns(filedownloader._pagerankreturn, thread);             removefrominternalpool(thread);             startdownload();          }            delegate void delsetstatus(string status, filedownloader f);       private void pagerankreturns(string status, filedownloader f)             {                 if (listviewurl.invokerequired)                 {                     delsetstatus s = new delsetstatus(pagerankreturns);                     this.invoke(s, new object[] { status, f });                 }                 else                 {                     foreach (listviewitem item in listviewurl.items)                     {                         if (item.tag == f)                         {                             /* use locking synchronise across mutilple thread calls. */                             lock (_lockobject)                             {                                 item.subitems[2].text = status;                              }                             break;                         }                     }                 }             }     private void removefrominternalpool(filedownloader thread)         {             int = 0;             foreach (filedownloader f in _instances)             {                 if (f == thread)                 {                     /* if file has downloaded, remove our pool. */                     lock (_lockobject)                     {                         _threads.remove(_threads[i]);                         _instances.remove(f);                         break;                     }                 }                 i++;             }         } 

/// second class ///

#region  fields  private string _documenturl = string.empty; private string _directorypath = string.empty; public bool _isdownloading = false; public bool _isdownloadsuccessful = false;  public bool _isstarted = false;  #endregion  #region delegates public delegate void _deldownloadstarting(filedownloader thread); public delegate void _deldownloadcompleted(filedownloader thread, bool issuccess); public delegate void _deldownloadcworking(filedownloader thread);  #endregion  #region events public event _deldownloadstarting downloadstarting; public event _deldownloadcompleted downloadcompleted;  protected static readonly object locker = new object(); public static string pagetitleresult= string.empty;  public static string _pagetitleresult {     { return pagetitleresult; } }  public filedownloader(string documenturl) {     _documenturl = documenturl; } 

//download method //

public void download() {     _isstarted = true;     downloadstarting(this);                 _isdownloading = true;     _isdownloadsuccessful = false;      // lock keyword works 1 one//     //without lock or monitor.enter keyword works tried explain above u1 = r1, u2 = r1, ur3 = r1, u4=r3 etc...      try     {         string pagehtml = gethtml(_documenturl);         htmlagilitypack.htmldocument htmldoc = new htmlagilitypack.htmldocument();          //html agibility works returned string gethtml...       // string pagetitle = html agibility work result, it's string...        pagetitleresult = pagetitle           _isdownloadsuccessful = true;         _isdownloading = false;         /* raise download completed event. */         downloadcompleted(this, _isdownloadsuccessful);     }     catch     {         _isdownloadsuccessful = false;     }    thread.sleep(10); } 

lock object :

protected static readonly object locker = new object(); 

well, made example in excel show how works...

this return without lock keyword : without lock keyword method

this lock keyword, way, in example, fired 5 threads waits first one's end... enter image description here

and i'm trying do... enter image description here

i think, problem in method:

private void pagerankreturns(string status, filedownloader f) {             if (listviewurl.invokerequired)             {                 delsetstatus s = new delsetstatus(pagerankreturns);                 this.invoke(s, new object[] { status, f });             }             else             {                 foreach (listviewitem item in listviewurl.items)                 {                     if (item.tag == f)                     {                         /* use locking synchronise across mutilple thread calls. */                         lock (_lockobject)                         {                             item.subitems[2].text = status;                          }                         break;                     }                 }             } } 

you must change structure of application. see method above ("pagerankreturns"). run cycle on items of listview, find item filedownloader. why filedownloader did know nothing item? if filedownloader know item, not need of cycle. , have explicit link between filedownloader , item.


Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -