2013-11-02 2 views
1
public void printMessage(string message) 
{ 
    try 
    { 
     if (this.InvokeRequired) 
     { 
      try 
      { 
       this.Invoke(new WriteLineHandler(printMessage), new object[] { message }); 
      } 
      catch (Exception) 
      { 
      } 
     } 
     else 
     { 
      if (message.Length > 0) 
      { 
       StringBuilder sb = new StringBuilder(); 
       sb.Append(DateTime.Now.ToString("G")); 
       sb.Append(": "); 
       sb.Append(message); 
       sb.Append("\n"); 
       sb.Append(richTextBox.Text); 
       richTextBox.Text = sb.ToString(); 
      } 
     } 
    } 
    catch (Exception) 
    { 
    } 
} 

this.Invoke(new WriteLineHandler(printMessage), new object[] { message }); Эта линия занимает много времени для выполнения. Может кто-нибудь помочь мне увеличить производительность.Вопрос о выпуске для делегатов

+2

Сколько это стоит времени? Долго по сравнению с вашими ожиданиями или другим кодом? – Szymon

+0

У меня есть API, который выполняет 10000 раз, и это заняло 2 часа. Если я удалю эту строку this.Invoke (новый WriteLineHandler (printMessage), новый объект [] {message}); он выполняется всего за 11 минут. Поэтому есть много изменений, но я не понимаю, как свести к минимуму этот код. Пожалуйста, помогите мне –

+0

Что ** ** ** ваш метод 'Invoke'? Вы можете вызвать метод напрямую, 'printMessage (message);'? Может быть, ваша настоящая проблема - непреднамеренная бесконечная рекурсия? –

ответ

0

Предложения:

Вы создаете два объекта каждый раз. Вы можете попытаться сохранить один или оба из них. Массив объекта, например, является очевидным соперником. Просто объявите статическую в методе, затем замените/установите первый элемент на новое значение сообщения при вызове.

Такой же подход может использоваться для экземпляра WriteLineHandler.

EDIT2: Извините, привинтил пример в первый раз.

EDIT:

Как уже было сказано другими, это, вероятно, не будет вашей головой. Тем не менее, нет необходимости платить за создание массива каждый раз.

Пример:

try { 
    static object[] messageAsArray = { "dummy" }; 
    messageAsArray[0] = message; 
    this.Invoke(new WriteLineHandler(printMessage), messageAsArray); 
} 
    catch (Exception) 
{ 
      } 
+0

Можете ли вы показать мне, как это сделать .. –

+0

можно использовать статическое ключевое слово для делегатов –

+0

Добавлен пример. –

2

this.Invoke здесь не просто делегировать вызов: он посылает сообщение в поток пользовательского интерфейса через цикл обработки сообщений. У этого есть накладные расходы, поэтому: попробуйте выполнить работу, чтобы сделать - так вы называете это реже, но с большим количеством «вещей» в каждом.

Существует также некоторые накладные расходы здесь с типом делегирования - только некоторые из них явно проверяются для быстрого/типизированного вызова - MethodInvoker - один, iirc, но это без параметров. Вы можете использовать замыкание подделать это, хотя:

MethodInvoker method =() => { … }; 
this.Invoke(method, null); 

(обратите внимание EventHandler также специальные обсаженным, все остальные типы делегатов будут использовать DynamicInvoke, что гораздо медленнее - но опять-таки: основные накладные расходы здесь являются UI цикл сообщений)

+0

Как мы выполняем фоновый поток в UI-потоке? –

+0

@ user2862430 вопрос не «как это сделать» - это «как *** часто *** это делать». 100 000 отдельных вызовов с одним значением значительно дороже 1000 вызовов, каждый из которых имеет 100 значений. * How * является 'Control.Invoke', в соответствии с кодом в вопросе (но, возможно, с помощью 'MethodInvoker', чтобы немного помочь) –

+0

его рабочий тон ... но нет улучшения в производительности –

Смежные вопросы