2016-09-08 4 views
0

У меня есть простая метка состояния, которую я часто обновляю во время продолжительной работы. Процедура находится на таймере и, следовательно, на другом потоке, поэтому я получаю ошибку Cross-thread operation not valid. Я нашел исправить на SO, который выглядит следующим образом:Объект доступа, созданный другим потоком без вызова каждый раз?

lblQuery1Status.Invoke(new Action(delegate 
{ 
    lblQuery1Status.Text = "Status: Publishing"; 
})); 

Однако я обновляю текст этого элемента управления 7 или 8 раз в течение дня. Есть ли более эффективный или простой способ сделать это?

+2

Что неэффективно? Если вам нужно сделать это 7-8 раз, вставьте его в метод со статусом как ввод строки. Я смотрю на вашего представителя, и я действительно не пытаюсь быть забавным - просто любопытно, что вы общаетесь, когда говорите эффективно? –

+0

Наверное, мне было интересно, могу ли я вызвать его один раз в новом потоке, а не каждый раз, когда мне нужно получить к нему доступ. Я новичок в '.net' и особенно в потоковом режиме. –

ответ

3

Если вы хотите, чтобы «упростить» синтаксис, вы всегда можете использовать встроенную лямбду «укоротить» синтаксис:

lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing")); 

вы также можете создать переменные действия для Invoke и повторно вызывать действие по мере необходимости :

Action updateStatus =() => 
    lblQuery1Status.Invoke(new Action(() => lblQuery1Status.Text = "Status: Publishing")); 

Вы можете вызвать его как метод столько раз, сколько необходимо:

updateStatus(); 
+0

Да, я знал, что 'invoke' не создает новые потоки, я просто надеялся, что есть способ вызвать его один раз * на * новый поток и ссылаться на него несколько раз после (без вызова каждый раз) –

+0

@Scott ah, виноват. Подходит ли последнее обновление ближе к тому, что вы ищете? –

+0

Определенно, ручка действия выглядит интересной. Я исследую это. Благодарю. –

0

Unfortunatley это лучший способ, чтобы получить данные с длиной хода задачи/нить в потоке пользовательского интерфейса, сортировочных имеет свои накладные расходы, но если вы не называть его сотни раз в секунду, я думаю, вам будет хорошо

1

Это решение, которое я пошел с, основанный на @David L «s answer above.

определение Действие:

Action<string> updateStatus = (s) => 
    statusLabel[qo.id].Invoke(new Action(() => statusLabel[qo.id].Text = s)); 

Вызов:

updateStatus("Opening Connection"); 

Я понимаю, что это не более эффективным, но это намного проще и чище, и это заставляет меня съежиться меньше.

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