SynchronizationContext.Post to UI Method

后端 未结 2 507
我在风中等你
我在风中等你 2020-12-11 17:54

I\'m working with web services so its necessary for me to extend session length/reconnect and get large datasets back etc. Sometimes this can be lengthy so I wanted it in a

相关标签:
2条回答
  • 2020-12-11 18:23

    Typically you are creating instances of your types (e.g. ViewModels) on the UI thread, so you can just save the SynchronizationContext or the TaskScheduler (preferable IMHO) to a private field and then compare it when needed...

    private readonly SynchronizationContext _syncContext = SynchronizationContext.Current;
    private readonly TaskScheduler _scheduler = TaskScheduler.Current;
    
    void OnSomeEvent(object sender, EventArgs e)
    {
        if (_syncContext != SynchronizationContext.Current)
        {
            // Use Send if you need to get something done as soon as possible.
            // We'll be polite by using Post to wait our turn in the queue.
            _syncContext.Post(o => DoSomething(), null);
            return;
        }
        // Call directly if we are already on the UI thread
        DoSomething();
    }
    
    void OnSomeOtherEvent(object sender, MyEventArgs e)
    {
        var arg1 = e.Arg1; // "Hello "
        var arg2 = e.Arg2; // {"World", "!"};
    
        // Process args in the background, and then show the result to the user...
        // NOTE: We don't even need to check the context because we are passing
        // the appropriate scheduler to the continuation that shows a MessageBox.
    
        Task<string>.Factory.StartNew(() => ReturnSomething(arg1, arg2))
            .ContinueWith(t => MessageBox.Show(t.Result), _scheduler);
    }
    
    void DoSomething() { MessageBox.Show("Hello World!"); }
    
    string ReturnSomething(string s, IEnumerable<string> list)
    {
        return s + list.Aggregate((c, n) => c + n);
    }
    
    0 讨论(0)
  • 2020-12-11 18:46

    You need a delegate of type SendOrPostCallback. Which is pretty awkward, it only takes a single argument of type object. You definitely ought to look at the Task<> class available in .NET 4 to make this easier. Or use a lambda, like this:

            string conn_name = "foo";
            uiContext.Post(new SendOrPostCallback((o) => {
                updateConnStatus(conn_name, true);
            }), null);
    

    The code between the { braces } executes on the UI thread.

    0 讨论(0)
提交回复
热议问题