RunAsync - How do I await the completion of work on the UI thread?

前端 未结 4 704
野趣味
野趣味 2020-12-05 08:42

When awaiting Dispatcher.RunAsync the continuation occurs when the work is scheduled, not when the work has completed. How can I await the work completing?

4条回答
  •  悲哀的现实
    2020-12-05 09:05

    A nice way to work the clean way @StephenCleary suggests even if you have to start from a worker thread for some reason, is to use a simple helper object. With the object below you can write code like this:

        await DispatchToUIThread.Awaiter;
        // Now you're running on the UI thread, so this code is safe:
        this.textBox.Text = text;
    

    In your App.OnLaunched you have to initialize the object:

        DispatchToUIThread.Initialize(rootFrame.Dispatcher);
    

    The theory behind the code below you can find at await anything;

    public class DispatchToUIThread : INotifyCompletion
    {
        private readonly CoreDispatcher dispatcher;
    
        public static DispatchToUIThread Awaiter { get; private set; }
    
        private DispatchToUIThread(CoreDispatcher dispatcher)
        {
            this.dispatcher = dispatcher;
        }
    
        [CLSCompliant(false)]
        public static void Initialize(CoreDispatcher dispatcher)
        {
            if (dispatcher == null) throw new ArgumentNullException("dispatcher");
            Awaiter = new DispatchToUIThread(dispatcher);
        }
    
        public DispatchToUIThread GetAwaiter()
        {
            return this;
        }
    
        public bool IsCompleted
        {
            get { return this.dispatcher.HasThreadAccess; }
        }
    
        public async void OnCompleted(Action continuation)
        {
            if (continuation == null) throw new ArgumentNullException("continuation");
            await this.dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => continuation());
        }
    
        public void GetResult() { }
    }
    

提交回复
热议问题