如何取消Device.BeginInvokeOnMainThread()?

时间:2017-12-29 10:53:27

标签: c# xamarin xamarin.forms

我有这段代码:

Device.BeginInvokeOnMainThread(() => Show().ContinueWith((arg) => { }));

public async Task Show()
{
   while (true)
   {
      await Task.Delay(500);
      Debug.WriteLine("test1");
      while (true)
      {
         await Task.Delay(500);
         Debug.WriteLine("test2");
      }
   }
}

我知道如果我有一项任务我可以取消它但是对于这段代码。如果例如它在循环中运行并且我想从该方法之外取消,我该如何取消Show()的执行?

请注意,我添加了

.ContinueWith((arg)

因为它阻止我的IDE发出错误。

此处参考Xamarin的DEVICE课程

public static class Device
{
    //
    // Static Fields
    //
    public const string iOS = "iOS";

    public const string Android = "Android";

    public const string WinPhone = "WinPhone";

    public const string UWP = "UWP";

    public const string WinRT = "WinRT";

    public const string macOS = "macOS";

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static DeviceInfo info;

    private static IPlatformServices s_platformServices;

    //
    // Static Properties
    //
    [EditorBrowsable (EditorBrowsableState.Never)]
    public static IReadOnlyList<string> Flags {
        [CompilerGenerated]
        get;
        [CompilerGenerated]
        private set;
    }

    public static TargetIdiom Idiom {
        [CompilerGenerated]
        get;
        [CompilerGenerated]
        internal set;
    }

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static DeviceInfo Info {
        get;
        set;
    }

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static bool IsInvokeRequired {
        get;
    }

    [Obsolete ("TargetPlatform is obsolete as of version 2.3.4. Please use RuntimePlatform instead.")]
    public static TargetPlatform OS {
        get;
    }

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static IPlatformServices PlatformServices {
        get;
        set;
    }

    public static string RuntimePlatform {
        get;
    }

    //
    // Static Methods
    //
    public static void BeginInvokeOnMainThread (Action action);

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static Assembly[] GetAssemblies ();

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static double GetNamedSize (NamedSize size, Type targetElementType, bool useOldSizes);

    public static double GetNamedSize (NamedSize size, Element targetElement);

    public static double GetNamedSize (NamedSize size, Type targetElementType);

    internal static Task<Stream> GetStreamAsync (Uri uri, CancellationToken cancellationToken);

    [Obsolete ("OnPlatform is obsolete as of version 2.3.4. Please use switch(RuntimePlatform) instead.")]
    public static void OnPlatform (Action iOS = null, Action Android = null, Action WinPhone = null, Action Default = null);

    [Obsolete ("OnPlatform<> (generic) is obsolete as of version 2.3.4. Please use switch(RuntimePlatform) instead.")]
    public static T OnPlatform<T> (T iOS, T Android, T WinPhone);

    public static void OpenUri (Uri uri);

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static void SetFlags (IReadOnlyList<string> flags);

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static void SetIdiom (TargetIdiom value);

    [EditorBrowsable (EditorBrowsableState.Never)]
    public static void SetTargetIdiom (TargetIdiom value);

    public static void StartTimer (TimeSpan interval, Func<bool> callback);

    //
    // Nested Types
    //
    public static class Styles
    {
        public static readonly string TitleStyleKey;

        public static readonly string SubtitleStyleKey;

        public static readonly string BodyStyleKey;

        public static readonly string ListItemTextStyleKey;

        public static readonly string ListItemDetailTextStyleKey;

        public static readonly string CaptionStyleKey;

        public static readonly Style TitleStyle;

        public static readonly Style SubtitleStyle;

        public static readonly Style BodyStyle;

        public static readonly Style ListItemTextStyle;

        public static readonly Style ListItemDetailTextStyle;

        public static readonly Style CaptionStyle;
    }
}

1 个答案:

答案 0 :(得分:2)

Device无关,但如何取消Action

您将使用CancellationTokenSource。 (因为它是在Xamarin的文档中,我相信它可供您使用)

private CancellationTokenSource _cts;

void Handler1()
{
    _cts = new CancellationTokenSource();
    Device.BeginInvokeOnMainThread(() => Show(_cts.Token).ContinueWith((arg) => { }));
}

void Handler2()
{
    if (_cts != null)
    {
        _cts.Cancel(); // <---- Cancel here
    }
}

public async Task Show(CancellationToken ct)
{
    while (true)
    {
        await Task.Delay(500, ct); // <-- Thanks to @Evk's suggestion
        Debug.WriteLine("test1");

        if (ct.IsCancellationRequested)
        {
            // another thread decided to cancel
            Console.WriteLine("Show canceled");
            break;
        }
    }
}

参考文章:https://stackoverflow.com/a/4783890/2710486