Как создать и вызвать метод (используя Thread C #) для каждого цикла?

#multithreading #visual-studio-2008

#многопоточность #visual-studio-2008

Вопрос:

Я хотел вызвать свой пользовательский метод в потоке.

  public void LoopOverAllLists(String _webAndSiteXml)
    {
        try
        {

            XmlNode _nodelist = SharePoint.ListsGetListCollection();

            foreach (System.Xml.XmlNode _item in _nodelist.ChildNodes)
            { 

                string title = _item.Attributes["Title"].Value;
                //check for hidden list
                if (_item.Attributes["Hidden"].Value.ToLower() == "false")
                {
                    switch (_item.Attributes["ServerTemplate"].Value)
                    {
                        //Check whether list is document library  
                        case SharePoint.LIST_ID_DOCUMENT_LIBRARY:
                        case SharePoint.LIST_ID_XML_FORMS:
                        case SharePoint.Publishing_ID_Pages:
                            {
                                //Get all documents info
                                try
                                {

                                    GetAllDocumentsInfo(_item, _webAndSiteXml);

                                }
                                catch
                                {

                                }

                                break;
                            }
                        //Check whether list is having attachment
                        case SharePoint.LIST_ID_GENERIC:
                        case SharePoint.LIST_ID_ANNOUNCEMENTS:
                        case SharePoint.LIST_ID_CONTACTS:
                        case SharePoint.LIST_ID_TASKS:
                        case SharePoint.LIST_ID_EVENTS:
                        case SharePoint.LIST_ID_CUSTOM_GRID:
                        case SharePoint.LIST_ID_MEETING_SERIES:
                        case SharePoint.LIST_ID_MEETING_AGENDA:
                        case SharePoint.LIST_ID_MEETING_ATTENDEES:
                        case SharePoint.LIST_ID_MEETING_DECISIONS:
                        case SharePoint.LIST_ID_MEETING_OBJECTIVES:
                        case SharePoint.LIST_ID_MEETING_TTB:
                        case SharePoint.LIST_ID_MEETING_WS_PAGES:
                        case SharePoint.LIST_ID_PORTAL_SITE_LIST:
                            {
                                //Get all list items info having attachment 
                                try
                                {
                                    GetAllListItemsInfoOnlyAttachments(_item, _webAndSiteXml);
                                }
                                catch
                                {

                                }

                                break;

                            }
                        default:
                            GetAllListItemsInfoOnlyAttachments(_item, _webAndSiteXml);
                            break;

                    }
                    // Get All the List Forms  
                    try
                    {
                        GetAllListForms(title, _webAndSiteXml);
                    }
                    catch
                    {

                    }

                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
  

в приведенном выше методе три метода, которые являются «GetAllDocumentsInfo , GetAllListItemsInfoOnlyAttachments и GetAllListForms «, я хотел вызвать эти функции, используя thread на C #.

Спасибо

Ответ №1:

Вот как я бы подошел к проблеме. Обратите внимание, что я инкапсулировал содержимое foreach цикла в отдельный метод, а затем поместил выполнение этого метода в ThreadPool очередь, чтобы каждая итерация цикла выполнялась параллельно. Я также использую хорошо зарекомендовавший себя шаблон для ожидания завершения всех ожидающих выполнения рабочих элементов. Этот код совместим с .NET 3.5.

 public void LoopOverAllLists(String _webAndSiteXml)
{
  int pending = 1; // Used to track the number of pending work items.
  var finished = new ManualResetEvent(false); // Used to wait for all work items to complete.
  XmlNode nodes = SharePoint.ListsGetListCollection();
  foreach (XmlNode item in nodes)
  {
    XmlNode capture = item; // This is required to capture the loop variable correctly.
    Interlocked.Increment(ref pending); // There is another work item in progress.
    ThreadPool.QueueUserWorkItem(
      (state) =>
      {
        try
        {
          ProcessNode(capture);
        }
        finally
        {
          // Signal the event if this is the last work item to complete.
          if (Interlocked.Decrement(ref pending) == 0) finished.Set();
        }
      }, null);
  }
  // Signal the event if the for loop was last work item to complete.
  if (Interlocked.Decrement(ref pending) == 0) finished.Set();
  // Wait for all work items to complete.
  finished.WaitOne();
}

private void ProcessNode(XmlNode item)
{
  // Put the contents of your loop here.
}
  

Ответ №2:

вместо вызова

 GetAllDocumentsInfo(_item, _webAndSiteXml);
  

использовать

 Task.Factory.StartNew(() => GetAllDocumentsInfo(_item, _webAndSiteXml));
  

повторите этот шаблон и для других вызовов метода

Комментарии:

1. Задача. У Factory нет ключевого слова mutex или join для присоединения к потоку?

2. Я решил не затрагивать проблемы синхронизации, поскольку он не спрашивал. Я уверен, что ему также нужно будет обратиться к этому, и библиотека задач в .NET 4, вероятно, сможет доставить его туда, куда ему нужно

3. @ricky библиотека задач является новой в .NET 4