目前有一个安装的功能,想在安装过程中让loading的图片加载出来,目前的情况貌似是要等到OnClick的方法执行完才会显示,但是安装过程比较长,程序就像假死了,有没有什么办法可以解决
1 通过多线程/异步执行process安装,解决住界面卡死的问题
2 通过splashScreen表示正在安装,当安装完成时给一个标志,结束splashScreen
我是异步执行的,但是异步里面提示调用线程无法访问此对象,因为另一个线程拥有该对象。正在看问题
@灬丶: application.current.dispatch.invoke(()=>{
//your code
});
@猝不及防: 我试下,谢了
首先应该避免在OnClick事件处理函数中去做任何耗时操作,这是UI线程,UI线程的时间片是很昂贵的,尽可能去做渲染的工作。在UI线程执行耗时操作会严重影响界面的渲染,导致无响应,你说的gif应该是指的忙指示器,肯定也没法渲染。
这样的场景在我们做过的系统中非常普遍,于是封装了一些好用的扩展方法,最常用的是异步线程执行耗时操作并显示忙指示器,异步执行完毕再切换回UI线程执行界面刷新。
using System;
using System.Threading.Tasks;
namespace Frontier.Wif.Utilities.Extensions
{
/// <summary>
/// Defines the <see cref="TaskExtensions" />
/// </summary>
public static class TaskExtensions
{
#region Methods
/// <summary>
/// 延时异步执行方法。
/// </summary>
/// <param name="action">待执行方法</param>
/// <param name="delayTime">延时时间(毫秒)</param>
public static void DelayRun(this Action action, int delayTime)
{
Task.Delay(delayTime).ContinueWith(unusedTask => action());
}
/// <summary>
/// The Run
/// </summary>
/// <param name="workAction">The action<see cref="Action"/></param>
/// <param name="completedAction">The completedAction<see cref="Action"/></param>
/// <param name="runCompletedActionInUIThread">The runCompletedActionInUIThread<see cref="bool"/></param>
/// <returns>The <see cref="Task"/></returns>
public static Task RunAsync(this Action workAction, Action completedAction,
bool runCompletedActionInUIThread = true)
{
var taskScheduler = runCompletedActionInUIThread
? TaskScheduler.FromCurrentSynchronizationContext()
: TaskScheduler.Current;
return Task.Run(workAction).ContinueWith(unusedTask => completedAction(), taskScheduler);
}
/// <summary>
/// The Run
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="workAction">The action<see cref="Action"/></param>
/// <param name="completedFunction">The completedFunction<see cref="Func{TResult}"/></param>
/// <param name="runCompletedActionInUIThread">The runCompletedActionInUIThread<see cref="bool"/></param>
/// <returns>The <see cref="Task{TResult}"/></returns>
public static Task<TResult> RunAsync<TResult>(this Action workAction, Func<TResult> completedFunction,
bool runCompletedActionInUIThread = true)
{
var taskScheduler = runCompletedActionInUIThread
? TaskScheduler.FromCurrentSynchronizationContext()
: TaskScheduler.Current;
return Task.Run(workAction).ContinueWith(unusedTask => completedFunction(), taskScheduler);
}
/// <summary>
/// The Run
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="workFunction">The function<see cref="Func{TResult}"/></param>
/// <param name="completedAction">The completedAction<see cref="Action"/></param>
/// <param name="runCompletedActionInUIThread">The runCompletedActionInUIThread<see cref="bool"/></param>
/// <returns>The <see cref="Task{TResult}"/></returns>
public static Task<TResult> RunAsync<TResult>(this Func<TResult> workFunction, Action<TResult> completedAction,
bool runCompletedActionInUIThread = true)
{
var taskScheduler = runCompletedActionInUIThread
? TaskScheduler.FromCurrentSynchronizationContext()
: TaskScheduler.Current;
var task = Task.Run(workFunction);
task.ContinueWith(unusedTask => completedAction(task.Result), taskScheduler);
return task;
}
/// <summary>
/// The Run
/// </summary>
/// <typeparam name="TWorkResult"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="workFunction">The workFunction<see cref="Func{TWorkResult}"/></param>
/// <param name="completedAction">The completedAction<see cref="Func{TWorkResult, TResult}"/></param>
/// <param name="runCompletedActionInUIThread">The runCompletedActionInUIThread<see cref="bool"/></param>
/// <returns>The <see cref="Task{TResult}"/></returns>
public static Task<TResult> RunAsync<TWorkResult, TResult>(this Func<TWorkResult> workFunction,
Func<TWorkResult, TResult> completedAction,
bool runCompletedActionInUIThread = true)
{
var taskScheduler = runCompletedActionInUIThread
? TaskScheduler.FromCurrentSynchronizationContext()
: TaskScheduler.Current;
return Task.Run(workFunction).ContinueWith(workTask => completedAction(workTask.Result), taskScheduler);
}
/// <summary>
/// The Run
/// </summary>
/// <param name="workTask">The workTask<see cref="Task"/></param>
/// <param name="completedAction">The completedAction<see cref="Action"/></param>
/// <param name="runCompletedActionInUIThread">The runCompletedActionInUIThread<see cref="bool"/></param>
/// <returns>The <see cref="Task"/></returns>
public static Task RunAsync(this Task workTask, Action completedAction,
bool runCompletedActionInUIThread = true)
{
var taskScheduler = runCompletedActionInUIThread
? TaskScheduler.FromCurrentSynchronizationContext()
: TaskScheduler.Current;
if (workTask.Status == TaskStatus.Created)
workTask.Start();
return workTask.ContinueWith(unusedTask => completedAction(), taskScheduler);
}
#endregion
}
}
代码来自我的一个开源项目wif ,里边有大量的扩展。