Reputation: 36048
How could I call the onCompleteCallBack
method on the same thread the SomeAsyncMethod
was called ?
public void SomeAsycMethod ( Action<object> onCompleteCallBack )
{
// get the current thread
/* var ThisThread = Thread.CurrentThread. */
Task.Factory.StartNew( () =>
{
Thread.Sleep( 1000 );// do some work;
// lastly call the onCompleteCallBack on 'ThisThread'
onCompleteCallBack( "some result" );
// I am looking for something like:
/* ThisThread.Invoke("some result"); */
});
}
Upvotes: 6
Views: 3347
Reputation: 11647
Actually if you're using Task-based asynchronous programming I suggested you refactor your code to return Task<T>
and give an ability to your client itself to decide in what context to call callback method (and facilitate future migration to C# 5.0 ;):
public Task<string> SomeMethodAsync()
{
return Task.Factory.StartNew(() => "some result");
}
If you definitely know that you're going to call this method from UI thread you can use following:
var task = SomeMethodAsync();
task.ContinueWith(t => textBox.Text = t.Result, TaskScheduler.FromSynchronizationContext);
This approach is better because it provide more clear separation of concern and give an ability to use your asynchronous method in any context without any dependencies to synchronization context. Some client can call this method from UI thread (and in this case TaskScheduler.FromSynchronizationContext
would behave as expected - your "continuation" would be called in UI thread), some of them could use your method from non-UI thread as well without such requirements like processing results in the same thread that initiate asynchronous operation.
Task<T>
is a perfect class that represents asynchronous operation as a first class object that helps not only obtain only more declarative code but more clear, easy to read and easy to test (you can easily mock this method and return "fake" task object).
Upvotes: 4
Reputation: 38116
While you can't guarantee you callback will be called on the same thread, you can guarantee it will be called in the same Synchronization Context (assuming one exists in the original call).
public void SomeAsycMethod ( Action<object> onCompleteCallBack )
{
// get the current context
var context = SynchronizationContext.Current;
Task.Factory.StartNew( () =>
{
Thread.Sleep( 1000 );// do some work;
// lastly call the onCompleteCallBack on 'ThisThread'
onCompleteCallBack( "some result" );
// I am looking for something like:
context.Post(s => onCompleteCallBack ("some result"), null);
});
}
For example, in a Windows Forms or WPF program, the above will make sure that the callback is called on the GUI thread (via the message loop or dispatcher, accordingly). Similarly for ASP.NET context.
Having said that, I agree with Justin Harvey in that returning a Task<T>
will probably be a better design.
Upvotes: 6