2015-08-18 10 views
2

Я пытаюсь выяснить, как потоки работают на мобильном устройстве Windows (6.0) с компактным каркасом 2.0. На данный момент я пытаюсь сделать индикатор выполнения, поскольку это одна из самых простых вещей и в основном в каждом учебнике, которое я нашел.Резьбовые окна mobile 6 compact framework

От нормальных форм окон - приложения я привык делать что-то вроде:

for (int i = 0; i < 10; i++) 
{ 
    myProgressBar.BeginInvoke(
    new Action(() => 
     { 
      myProgressBar.Value = i; 
      Thread.Sleep(100); 
     } 
    )); 
} 

Но я получаю ошибку при new Action(()...:

Использование типа "System.Action<T>" (общий) требует 1-Type аргумент
(перевод с немецкого)

Это кажется Action() не доступен для меня, только Action<T>(). Но я не знаю, какой должен быть параметр T или какой аргумент дать Action<T>().

+1

Кстати, рассмотрите возможность использования .NET CF 3.5 вместо 2.0 – tcarvin

ответ

1

Прежде всего, вы можете выполнить код, который вы не можете ожидать от него, поскольку вы используете замыкания здесь на переменной i, для правильной работы вам нужно скопировать i в локальную переменную. Кроме того, вы можете упростить свой код, а не создавать объект Action, но use simple lambda expression here, and convert it to Action.

Так что ваш окончательный код может выглядеть так (добавлены некоторые небольшие поправки для приращения и var ключевого слова):

for (var i = 0; i < 10; ++i) 
{ 
    var localI = i; 
    myProgressBar.BeginInvoke(
     (Action)(() => 
     { 
      myProgressBar.Value = localI; 
      Thread.Sleep(100); 
     } 
    )); 
} 

Как необщего класс не доступен для вас, вы можете бросить метод вы передаете в BeginInvoke в какой-то делегат из библиотеки стандартной, например, MethodInvoker (поддерживается в .NET Framework Client Profile ), и использовать не лямбда, но delegate ключевое слово для кода простоты:

for (var i = 0; i < 10; ++i) 
{ 
    var localI = i; 
    myProgressBar.BeginInvoke(
     (MethodInvoker) delegate() 
     { 
      myProgressBar.Value = localI; 
      Thread.Sleep(100); 
     } 
    ); 
} 

Но я хочу, чтобы вы знали, что Thread.Sleep здесь заморозит нить пользовательского интерфейса, а не фоновый, поскольку вы вызываете Action в теме цели. Так вы лучше поставить этот код из обновления пользовательского интерфейса:

for (var i = 0; i < 10; ++i) 
{ 
    var localI = i; 
    myProgressBar.BeginInvoke((MethodInvoker) delegate() 
     { 
      myProgressBar.Value = localI; 
     }); 
    Thread.Sleep(100); 
} 
+0

Спасибо за предложения. Однако главная проблема остается. '(Action)' не будет компилироваться, поскольку 'Action()' не является доступным. Единственное, что доступно, - «Действие ()'. Поэтому я должен указать тип и giva переменную этого типа. – FNR

+0

Вы попробовали? Вам не нужно создавать действие с помощью конструктора, требуется только кастинг). – VMAtm

+0

@FNR Что такое подпись для «BeginInvoke» точно? Можно ли его найти на MSDN? – VMAtm

1

При поиске альтернативы MethodInvoker как отметил @VMAtm я, наконец, нашел способ, который работает с компактной структурой:

for (int i = 0; i < 10; i++) 
{ 
    var localI = i; 
    myProgressBar.BeginInvoke(
    (ThreadStart)delegate() 
     { 
      myProgressBar.Value = localI; 
     } 
    ); 
    Thread.Sleep(100); 
} 
+0

О, забыл о опции 'ThreadStart'. – VMAtm