Thread.Sleep() в переносимой библиотеке классов

В документах 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>

person Aleksandr Dubinsky    schedule 12.02.2012    source источник
comment
Что говорит компилятор? Короткий, но полный пример, включающий сообщение об ошибке, может помочь.   -  person Jon Skeet    schedule 12.02.2012
comment
Проблема, вероятно, в настройке/конфигурации вашего проекта, но вы окажете пользователям библиотеки медвежью услугу. Так что не решайте эту проблему, а избавьтесь от Sleep().   -  person Henk Holterman    schedule 12.02.2012
comment
Согласитесь с @HenkHolterman здесь (я думаю). Какую проблему вы пытаетесь решить, что заставляет вас думать, что Thread.Sleep является правильным решением?   -  person Damien_The_Unbeliever    schedule 12.02.2012
comment
@JonSkeet System.Threading.Thread не содержит определения для «Сна». Этого также нет в интеллектуальном смысле. Код C# не имеет значения. Установку/конфигурацию проекта и машины разработчика передать сложнее. Я обновлю свой Q файлом проекта. По сути, это PCL, ориентированный на .NET 4 и Silverlight 4. Инструменты Portable Library Tools, которые я скачал и установил вчера, перейдя по ссылке здесь. VS 2010 — это SP1 со всеми обновлениями Microsoft.   -  person Aleksandr Dubinsky    schedule 13.02.2012
comment
@Damien_The_Unbeliever Я общаюсь с устройством через RS232, и мне нужно делать паузы.   -  person Aleksandr Dubinsky    schedule 13.02.2012
comment
Я не уверен, что вам нужен Sleep() для работы с COM-портом. Возможно, просмотрите множество вопросов о SerialPort для других идей.   -  person Henk Holterman    schedule 13.02.2012


Ответы (5)


Это неприятный побочный эффект «портативности». Библиотека становится легко переносимой путем вычитания, удаляя все части, недоступные только для одной из многих возможных целей. Это нанесло ущерб классу Thread, поскольку он совершенно лишен каких-либо полезных членов. Их осталось всего 5: MemoryBarrier(), CurrentCulture, CurrentThread, CurrentUICulture и ManagedThreadId.

Это может показаться странным, пересечение рекламируемых целей, безусловно, поддерживает больше. Вероятно, это связано с нерекламируемым. Предстоящая версия Windows 8, которая будет работать на ядрах ARM. Также известный как WinRT или Metro или API ".NET для приложений в стиле Metro", в зависимости от того, какие инструменты вы используете. WinRT сильно урезает традиционный Windows API, его пространство имен System.Windows.Threading практически пусто.

Это вызовет тонну вопросов по SO типа "Ээээ, а теперь что мне делать?". Возможный обходной путь здесь — сжечь фиктивный объект System.Threading.ManualResetEvent. У него есть метод WaitOne(TimeSpan).

Fwiw, я лично не с нетерпением жду программирования с этой библиотекой. Безусловно, самый тревожный лакомый кусочек находится в разделе вопросов и ответов по предоставленной вами ссылке:

В: Я хотел спросить, что случилось с методом Compile класса System.Linq.Expressions.Expression.
О: Он не поддерживается в Windows Phone/Xbox, поэтому он отображается только при использовании Silverlight + .NET. .

Ой. Портативный, спортивный. Это нужно какое-то время потушить. Мои симпатии DevDiv в целом и Дэвиду Кину в частности, тяжелая работа.

person Hans Passant    schedule 12.02.2012
comment
Я попытался найти ссылку на .NET для Metro, и похоже, что Thread.Sleep() находится там msdn.microsoft.com/en-us/library/windows/apps/ Но, возможно, сайт документации просто тормозит. msdn.microsoft.com/en -us/library/windows/apps/ четко говорит: в документации по типу указано, какие элементы включены в API-интерфейсы .NET для приложений в стиле Metro. - person Aleksandr Dubinsky; 13.02.2012
comment
Я предполагаю, что правильный способ сделать это в стиле Metro await TaskEx.Delay Есть ли асинхронный материал в PCL? Я проверю, но не думаю. - person Aleksandr Dubinsky; 13.02.2012
comment
О, и ваш превосходный ответ вызывает вопрос, как я могу настроить свой PCL, чтобы НЕ ориентироваться на Metro? Предположительно VS 11 предлагает гранулированность? - person Aleksandr Dubinsky; 13.02.2012
comment
Я не знаю этих вещей, пока это не окажется в моих руках. Бета-версия VS11 должна выйти в этом месяце. - person Hans Passant; 13.02.2012
comment
@AleksandrDubinsky await полностью отличается от Sleep - вы могли бы иметь в виду .Wait() ? - person Marc Gravell; 26.04.2012
comment
@MarcGravell немного отличается, не совсем. Thread.Sleep() приостанавливает выполнение и уступает другим потокам, в то время как await TaskEx.Delay приостанавливает выполнение и уступает другим потокам и волокнам. .Wait() не уступает волокнам, как Sleep(), но редко вам это нужно. - person Aleksandr Dubinsky; 30.04.2012
comment
@AleksandrDubinsky да, но await - это ContinueWith - что снова отличается - это только обратный вызов. - person Marc Gravell; 30.04.2012

(Я «владею» проектом портативной библиотеки в Microsoft)

К сожалению, это было поздним изменением в рабочей области проекта Portable Library, которое мы внесли, чтобы мы могли запускаться и ссылаться на приложения Metro. Одно из новшеств в приложениях в стиле Metro, Visual Studio 11 и Windows 8 заключается в том, что приложениям больше не нужно создавать собственные потоки и управлять ими (что сложно сделать правильно). Вместо этого идея состоит в том, что вы используете язык (т.е. async/await) и функции фреймворка (Task) для выполнения и синхронизации с операциями, которые должны выполняться в фоновом режиме.

Что использовать в качестве замены (например, ManualResetEvent, Task.Delay) полностью зависит от вашего сценария и целевых платформ. Можете ли вы объяснить, что вы делаете?

person David Kean    schedule 19.02.2012
comment
Вау, Дэвид Кин! У меня так много вопросов и неприятных вещей, чтобы сказать вам! Чтобы ответить, что я делаю, это управляю аппаратным устройством с открытым исходным кодом через последовательный порт. Сначала как настольное приложение, затем перенесено в Silverlight (используя P/Invoke или Java JNI... ПОЗОР на MS за то, что он убил поддержку RS232 в Silverlight и Metro). Что касается потоков, я их не использую, но async/Task их не заменяет. Однопоточный != Многопоточный. Это page по-прежнему говорит об использовании класса Thread для длительных задач в Metro. - person Aleksandr Dubinsky; 19.02.2012
comment
Что касается самого PCL, то я вижу много бессмысленной несовместимости. PCL должна приложить больше усилий, чтобы быть широко совместимой. Он должен быть толще и подражать функциональным возможностям, которые на 95% аналогичны, но были «отделены при рождении». Например, в PCL нет ни Thread.Sleep(), ни Task.Delay(). Это чистая удача, у него есть ManualResetEvent. Почему бы просто не включить Thread.Sleep() и не скомпилировать его как await Task.Delay() в Metro? Почему нет Enum.GetValues()? Почему нет ObservableCollection в .NET 4?! И т.д., и т.п. PCL практически бесполезен. - person Aleksandr Dubinsky; 19.02.2012
comment
У PCL должны быть «лица» (пространства имен и классы, которые должны быть представлены разработчику), чтобы классический .NET не стал единственным лицом по умолчанию. Тогда у него должно быть то, на что он нацелен. Цели должны быть мелкозернистыми, а не на уровне сборки. И должен быть (какой-то) прокладочный код для заполнения пробелов. Наконец, он должен распространяться на более широкую вселенную .NET, включая Micro Framework (например, Netduino). - person Aleksandr Dubinsky; 19.02.2012
comment
Наконец, я хочу видеть все фундаментальные сторонние библиотеки (т. е. контейнеры DI, тестовые фреймворки и т. д. и т. д.), нацеленные на PCL. Я много вложил в их изучение (и разработчики вложили в их создание), чтобы они были легко переносимы на любые инновации, которые придумывает MS. - person Aleksandr Dubinsky; 19.02.2012
comment
Спасибо за ответ. Мы работаем над улучшением поддержки, и я рекомендую вам загрузить бета-версию Visual Studio 11 и поделиться своим мнением. Как я рассказываю в своих Видео Channel 9 чрезвычайно сложно иметь вменяемую портативную историю для платформ, которые уже сделаны и отправлены. Переносимость постфактум работает не во всех ситуациях, например, пока мы не исправили это в 4.5, ObservableCollection не располагалась в одних и тех же местах на всех платформах. - person David Kean; 26.02.2012
comment
Мы внесли изменения в будущую платформу, чтобы эти, казалось бы, «случайные» отсутствующие API больше не встречались. Например, если вы выберете только «.NET 4.5» и «.NET для приложений в стиле Metro», вы получите каждый отдельный API, который является общим для них, но, к сожалению, это практически невозможно сделать для предыдущие версии. - person David Kean; 26.02.2012
comment
О, еще одна вещь, я думаю, вы можете неверно истолковать (я зарегистрировал внутреннюю ошибку, чтобы исправить документ), о чем говорится на странице Metro. В нем говорится о замене использования потока на использование задачи. Задача также не подразумевает однопоточность; Task.Run по умолчанию помещает работу в ThreadPool. - person David Kean; 26.02.2012
comment
Есть ли способ скомпилировать операторы #ifdef в PCL? Если бы эта функция была доступна, она значительно расширила бы совместимость и мощность PCL без каких-либо других моих предложений. Кроме того, планируете ли вы поддерживать второстепенные/устаревшие платформы, такие как .NET Micro или Silverlight? - person Aleksandr Dubinsky; 26.02.2012
comment
А что, если я хочу установить определенный приоритет потока? Насколько я понимаю, не рекомендуется менять приоритет потока задачи из-за пула потоков. Но как тогда создать поток с определенным приоритетом в PCL? - person JustAMartin; 22.05.2017

System.Threading.Tasks.Task.Delay(ms).Wait();

работает как заменитель

System.Threading.Thread.Sleep(ms);

Это прекрасно работает при переносе устаревшей кодовой базы.

person Andy Joiner    schedule 24.07.2015

Попробуйте подождать на http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx с тайм-аутом.

person usr    schedule 12.02.2012

Вы можете использовать Task.Delay в System.Threading.Tasks

person Keith Crompton    schedule 05.04.2015