Call method on UI thread from background in .net 2.0

我的未来我决定 提交于 2019-12-23 04:53:19

问题


I am using MonoDevelop (.net 2.0) to develop a iOS and Android app. I use BeginGetResponse and EndGetResponse to asynchronously do a webrequest in a background thread.

IAsyncResult result = request.BeginGetResponse(new AsyncCallback(onLogin), state);

However, the callback onLogin does seem to still be running on a background thread, no allowing me to interact with the UI. How do I solve this?

Can see that there are Android and iOS specific solutions but want a cross-platform solution.

Edit: From mhutch answer I've got this far:

IAsyncResult result = request.BeginGetResponse(o => {
            state.context.Post(() => { onLogin(o); });
        }, state);

Where state contains a context variable of type SynchronizationContext set to SynchronizationContext.Current

It complains that Post requires two arguments, the second one being Object state. Inserting state gives the error

Argument `#1' cannot convert `anonymous method' expression to type `System.Threading.SendOrPostCallback' (CS1503) (Core.Droid)

回答1:


Both Xamarin.iOS and Xamarin.Android set a SynchronizationContext for the GUI thread.

This means you get the SynchronizationContext.Current from the GUI thread and pass it to your callback (e.g via the state object or captured in a lambda). Then you can use the context's Post method to invoke things on the main thread.

For example:

//don't inline this into the callback, we need to get it from the GUI thread
var ctx = SynchronizationContext.Current;

IAsyncResult result = request.BeginGetResponse(o => {
    // calculate stuff on the background thread
    var loginInfo = GetLoginInfo (o);
    // send it to the GUI thread
    ctx.Post (_ => { ShowInGui (loginInfo); }, null);
}, state);



回答2:


I'm not sure if this works on Mono, but I usually do this on WinForm applications. Let's suppose you want to execute the method X(). Then:

public void ResponseFinished() {
    InvokeSafe(() => X()); //Instead of just X();
}

public void InvokeSafe(MethodInvoker m) {
    if (InvokeRequired) {
        BeginInvoke(m);
    } else {
        m.Invoke();
    }
}

Of course, this is inside a Form class.



来源:https://stackoverflow.com/questions/14997974/call-method-on-ui-thread-from-background-in-net-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!