线程窗口移动6紧凑框架

时间:2015-08-18 08:30:41

标签: c# multithreading lambda windows-mobile compact-framework

我正在试图弄清楚线程框架2.0在Windows移动设备(6.0)上的线程是如何工作的。现在我正在尝试制作一个进度条,因为它是最基本的东西之一,基本上在我发现的每个教程中。

从普通的Windows窗体 - 我以前用过的应用程序:

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>()提供什么参数。

2 个答案:

答案 0 :(得分: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中受支持 ),并且不使用lambda,而是使用delegate关键字来简化代码:

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

但是我希望您注意Thread.Sleep这里将冻结UI线程,而不是后台线程,因为您正在调用目标线程上的Action。 / strong>所以你最好把这些代码从UI更新中删除:

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

答案 1 :(得分:1)

在寻找@ MethodInvoker的替代方案时,我发现了一种适用于紧凑框架的方法:

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