Muh*_*eed 10 .net c# dispatcher task-parallel-library portable-class-library
在.NET,Windows 8和Windows Phone 7中,我的代码与此类似:
public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
{
if (dispatcher.CheckAccess())
{
action();
}
else
{
dispatcher.Invoke(action);
}
}
Run Code Online (Sandbox Code Playgroud)
我如何在便携式类库中做一些事情?有一个平台无关的实现这将是很好的.我的想法是使用WP7中没有的TPL,但肯定会很快.
// PortableDispatcher must be created on the UI thread and then made accessible
// maybe as a property in my ViewModel base class.
public class PortableDispatcher
{
private TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
public void Invoke(Action action)
{
if (Alread on UI thread. How would I do this.)
{
action();
}
Task.Factory.StartNew(
action,
CancellationToken.None,
TaskCreationOptions.None,
taskScheduler);
}
}
Run Code Online (Sandbox Code Playgroud)
我唯一不确定的是它的性能影响.也许我会做一些测试.
Ale*_*tof 14
您可以使用SynchronizationContext.Post或Send方法.它是可移植的,当您将UI框架与调度程序一起使用时,当前的同步上下文会将工作委派给Dispatcher.
具体来说,您可以使用以下代码:
void InvokeIfRequired(this SynchroniationContext context, Action action)
{
if (SynchroniationContext.Current == context)
{
action();
}
else
{
context.Send(action) // send = synchronously
// context.Post(action) - post is asynchronous.
}
}
Run Code Online (Sandbox Code Playgroud)
随着TPL的出现。我提出了一个稍微改进的已接受答案的版本,它返回一个任务,并且可以使用新的 async 和 await 关键字进行等待。
public Task RunAsync(Action action)
{
TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>();
if (this.synchronizationContext == SynchronizationContext.Current)
{
try
{
action();
taskCompletionSource.SetResult(null);
}
catch (Exception exception)
{
taskCompletionSource.SetException(exception);
}
}
else
{
// Run the action asyncronously. The Send method can be used to run syncronously.
this.synchronizationContext.Post(
(obj) =>
{
try
{
action();
taskCompletionSource.SetResult(null);
}
catch (Exception exception)
{
taskCompletionSource.SetException(exception);
}
},
null);
}
return taskCompletionSource.Task;
}
Run Code Online (Sandbox Code Playgroud)