【问题标题】:Thread.Sleep() in a Portable Class Library可移植类库中的 Thread.Sleep()
【发布时间】:2012-02-12 19:26:06
【问题描述】:

MSDN 文档说Thread.Sleep() 可以在可移植 类库中使用。编译器另有说明。除了自旋循环,我还有什么选择? Thread.CurrentThread.Join() 也不存在。

项目文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{C46B138E-CC30-4397-B326-8DD019E3874B}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>x0xtest.AVR</RootNamespace>
    <AssemblyName>x0xtest.AVR</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Profile3</TargetFrameworkProfile>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Attributes\AddressAttribute.cs" />
    <Compile Include="Attributes\RegAttribute.cs" />
    <Compile Include="Attributes\ROAttribute.cs" />
    <Compile Include="Attributes\RWAttribute.cs" />
    <Compile Include="Attributes\WOAttribute.cs" />
    <Compile Include="Devices\ATMega162.cs" />
    <Compile Include="Exceptions.cs" />
    <Compile Include="IntelHexFormat.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Proxy.cs" />
    <Compile Include="ProxyBase.cs" />
    <Compile Include="ProxyBase_UploadFirmware.cs" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\x0xtest.Comm\x0xtest.Comm.csproj">
      <Project>{F78547AC-1CA1-4ADB-9FA8-3E7DEB682240}</Project>
      <Name>x0xtest.Comm</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

【问题讨论】:

  • 编译器是怎么说的?一个简短但完整的示例(包括错误消息)会有所帮助。
  • 问题可能出在您项目的设置/配置中,但您会对 lib 的用户造成伤害。所以不要解决这个问题,而是摆脱 Sleep()。
  • 在这里同意@HenkHolterman(我认为)。您想要解决的什么问题让您认为Thread.Sleep 是正确的解决方案?
  • @JonSkeet “System.Threading.Thread 不包含‘睡眠’的定义”它也不属于智能感知。 C# 代码无关紧要。项目和开发机器的设置/配置更难传达。我将使用项目文件更新我的 Q。基本上,它是一个针对 .NET 4 和 Silverlight 4 的 PCL。我昨天通过链接here 下载并安装了便携式库工具。 VS 2010 是带有所有 Microsoft 更新的 SP1。
  • @Damien_The_Unbeliever 我正在通过 RS232 与设备通信,我需要暂停一下。

标签: c# portable-class-library


【解决方案1】:

这是“便携”的不幸副作用。库通过减法变得高度可移植,删除了许多可能目标之一上不可用的所有部分。这对 Thread 类造成了严重破坏,它完全没有任何有用的成员。只剩下 5 个,MemoryBarrier()、CurrentCulture、CurrentThread、CurrentUICulture 和 ManagedThreadId。

这可能看起来很奇怪,广告目标的交集肯定支持更多。这可能与未宣传的有关。即将在 ARM 内核上运行的 Windows 8 版本。也称为 WinRT 或 Metro 或“.NET for Metro 风格应用程序”API,具体取决于您使用的工具。 WinRT 严重削减了传统的 Windows API,它的 System.Windows.Threading 命名空间非常空。

这将产生 的关于 SO 的问题,“Eeek,现在我该做什么”之类的。这里可能的解决方法是烧掉一个虚拟的 System.Threading.ManualResetEvent 对象。它有一个 WaitOne(TimeSpan) 方法。

Fwiw,我个人并不期待针对这个库进行编程。到目前为止,最令人震惊的消息是在您提供的链接的问答部分:

问:我想问一下 Compile 的方法是怎么回事 System.Linq.Expressions.Expression 类。
答:Windows Phone/Xbox 不支持它,因此它仅在您以 Silverlight + .NET 为目标时才会显示。

哎哟。便携,运动。这需要炖一段时间。我总体上对 DevDiv 尤其是 David Kean 表示同情,这是一项艰巨的工作。

【讨论】:

  • 我试图为 Metro 寻找 .NET 的参考,看起来 Thread.Sleep() 在那里msdn.microsoft.com/en-us/library/windows/apps/… 但也许文档站点只是迟钝了。 msdn.microsoft.com/en-us/library/windows/apps/… 明确表示,“类型的文档表明哪些成员包含在 Metro 风格应用程序的 .NET API 中。”
  • 我猜 Metro 风格的正确方法是 await TaskEx.Delay PCL 中的异步内容吗?我会检查但猜不到。
  • 哦,您的出色回答引出了一个问题,如何将我的 PCL 配置为不针对 Metro?大概 VS 11 提供了粒度?
  • 我不知道这些东西,直到它在我手中。 VS11 的测试版将于本月发布。
  • @AleksandrDubinsky awaitSleep 完全不同 - 你可能是指 .Wait()
【解决方案2】:

(我“拥有”微软的可移植库项目)

不幸的是,这是对便携式图书馆项目表面区域的后期更改,以便我们可以运行并被 Metro 应用程序引用。 Metro 风格应用程序、Visual Studio 11 和 Windows 8 的新功能之一是无需应用程序创建和控制自己的线程(这很难做到正确)。相反,这个想法是您利用语言(即async/await)和框架功能(Task)来执行和同步应该在后台发生的操作。

使用什么作为替代品(例如,ManualResetEventTask.Delay),完全取决于您的场景和您的目标平台。你能解释一下你在做什么吗?

【讨论】:

  • 哇,大卫·基恩!我有很多问题和讨厌的事情要对你说!要回答,我正在做的是通过串行驱动开源硬件设备。首先作为桌面应用程序,然后转移到 Silverlight(使用 P/Invoke 或 Java JNI...MS 上的 SHAME 以终止 Silverlight 和 Metro 中的 RS232 支持)。关于线程,我不使用它们,但 async/Task 不能替代它们。单线程!=多线程。 This page 仍然说要在 Metro 中使用 Thread 类来处理长时间运行的任务。
  • 至于 PCL 本身,我看到了很多毫无意义的不兼容。 PCL 应该更加努力地实现广泛兼容。它应该更厚,并模拟 95% 类似但“在出生时分离”的功能位。例如,PCL 没有 Thread.Sleep() 也没有 Task.Delay()。拥有 ManualResetEvent 真是太幸运了。为什么不只包含 Thread.Sleep() 并将其编译为 Metro 上的 await Task.Delay() 呢?为什么没有 Enum.GetValues()?为什么 .NET 4 中没有 ObservableCollection?!等等等等。PCL几乎没用。
  • 感谢您的反馈。我们正在努力改进支持,我鼓励您下载 Visual Studio 11 Beta 并告诉我们您的想法。正如我在channel 9 video 中所说的,对于已经完成并已交付的平台,很难有一个理智的可移植故事。事后可移植性并非在所有情况下都有效,例如,直到我们在 4.5 中修复此问题之前,ObservableCollection 并非在所有平台上都位于相同的位置。
  • 我们已经对未来的平台进行了更改,以便不再出现这些看似“随机”缺失的 API。例如,如果您只选择“.NET 4.5”和“.NET for Metro 风格应用程序”,您将获得它们之间通用的每一个 API,不幸的是,这几乎是不可能的以前的版本。
  • 哦,还有一件事,我认为您可能误解了 Metro 页面的内容(我在内部提交了一个错误以修复文档)。就是说用任务使用替换线程使用。任务也不意味着单线程;默认情况下,Task.Run 会将工作放在 ThreadPool 上。
【解决方案3】:
System.Threading.Tasks.Task.Delay(ms).Wait();

可以直接替代

System.Threading.Thread.Sleep(ms);

这在移植旧代码库时可以正常工作。

【讨论】:

    【解决方案4】:
    【解决方案5】:

    你可以在System.Threading.Tasks中使用Task.Delay

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多