问题
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