Проблемы с System.Threading.Timer в профиле PCL 78 – Предупреждения

Я был удивлен, что удобный класс System.Threading.Timer не существует в библиотеках профиля 78. Чтобы использовать этот класс, я создал еще один PCL, который нацелен на фреймворк 4.0 и написал простую оболочку (как это было предложено в одном сообщении в блоге):

public class PCLTimer { private Timer timer; private Action<object> action; public PCLTimer (Action<object> action, object state, int dueTimeMilliseconds, int periodMilliseconds) { this.action = action; timer = new Timer (PCLTimerCallback, state, dueTimeMilliseconds, periodMilliseconds); } private void PCLTimerCallback (object state) { action.Invoke (state); } public bool Change (int dueTimeMilliseconds, int periodMilliseconds) { return timer.Change (dueTimeMilliseconds, periodMilliseconds); } } 

Теперь я могу ссылаться на эту библиотеку 4.0 и использовать PCLTimer в основной библиотеке PCL. Но когда я пытаюсь создать свой основной проект Android, я получаю следующие предупреждения:

 Warning CS1684: Reference to type 'System.Threading.Timer' claims it is defined in 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile78\mscorlib.dll', but it could not be found (CS1684) (Prototype.Core) Warning MSB3247: Found conflicts between different versions of the same dependent assembly. (MSB3247) (Prototype.Droid) 

Как правильно избавиться от этих предупреждений?

Ниже приведена полная повторная реализация класса Timer, который временно исчез в профиле 78, используя асинхронные задачи:

 using System; using System.Threading; using System.Threading.Tasks; namespace Quantum { public delegate void TimerCallback(object state); public sealed class Timer : IDisposable { private static Task CompletedTask = Task.FromResult(false); private TimerCallback Callback; private Task Delay; private bool Disposed; private int Period; private object State; private CancellationTokenSource TokenSource; public Timer(TimerCallback callback, object state, int dueTime, int period) { Callback = callback; State = state; Period = period; Reset(dueTime); } public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period) : this(callback, state, (int)dueTime.TotalMilliseconds, (int)period.TotalMilliseconds) { } ~Timer() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool cleanUpManagedObjects) { if (cleanUpManagedObjects) Cancel(); Disposed = true; } public void Change(int dueTime, int period) { Period = period; Reset(dueTime); } public void Change(TimeSpan dueTime, TimeSpan period) { Change((int)dueTime.TotalMilliseconds, (int)period.TotalMilliseconds); } private void Reset(int due) { Cancel(); if (due >= 0) { TokenSource = new CancellationTokenSource(); Action tick = null; tick = () => { Task.Run(() => Callback(State)); if (!Disposed && Period >= 0) { if (Period > 0) Delay = Task.Delay(Period, TokenSource.Token); else Delay = CompletedTask; Delay.ContinueWith(t => tick(), TokenSource.Token); } }; if (due > 0) Delay = Task.Delay(due, TokenSource.Token); else Delay = CompletedTask; Delay.ContinueWith(t => tick(), TokenSource.Token); } } private void Cancel() { if (TokenSource != null) { TokenSource.Cancel(); TokenSource.Dispose(); TokenSource = null; } } } } 

Вам нужно добавить привязку к app.config? Мне пришлось сделать что-то подобное для HttpClient, когда я добавил проект WP8.

 <?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="2.0.5.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration> 

Вместо того, чтобы помещать реализацию оболочки таймера в отдельный проект .net 4.0, я решил эту проблему по-другому:

Я создал интерфейс ITimerWrapper в основном проекте и поставил sepearate-реализации в проектах Droid и WinPhone. Затем я использую IoC для настройки требуемой реализации при запуске приложения.

Этот метод не противоречит различным версиям таймера с помощью PCL.

Еще одно преимущество – теперь я могу использовать DispatcherTimers в проекте WinPhone – я мог использовать только System.Threading.Timers, когда я делил код между Android и WinPhone.

Intereting Posts
API-интерфейсы Google google maps получают инструкции по программированию Android Market и имя файла APK Возврат пробных покупок при тестировании Google in-App Абстрактная активность Android в манифесте Как запрашивать события календаря Android для определенного диапазона дат? Как получить keyCode в android Перечислите активность с помощью заголовка, нижнего колонтитула и опустошите все видимые Android drawSelectorOnTop с GridView Запись ресурса com.crashlytics.android.build_id уже определена Intellij IDEA 14 – Пакет R не существует Android Studio 2.2, Gradle build не работает с java.lang.OutOfMemoryError: невозможно создать новый собственный поток Android – openCV, получите часть изображения – странное поведение OOD и Передача активности в качестве параметра для конструкторов других классов Как сохранить соотношение сторон android: groupIndicator в ExpandableListView? Ошибка Android Studio: Ошибка: CreateProcess error = 216, эта версия% 1 несовместима с версией Windows, в которой вы работаете