C# 处理来自BeginInvoke的异常的方法?
有时您需要在特定线程上运行特定代码,例如winforms。要在UI线程上运行代码,您需要以下内容:C# 处理来自BeginInvoke的异常的方法?,c#,.net,multithreading,C#,.net,Multithreading,有时您需要在特定线程上运行特定代码,例如winforms。要在UI线程上运行代码,您需要以下内容: this.BeginInvoke(new MethodInvoker(() => { try { //code } catch(Exception ex) { HandleException(ex); } } RunOnUIThread(MyMethod); SynchornixationContext是做同样事情的另一种方
this.BeginInvoke(new MethodInvoker(() =>
{
try
{
//code
}
catch(Exception ex)
{
HandleException(ex);
}
}
RunOnUIThread(MyMethod);
SynchornixationContext是做同样事情的另一种方式
假设我们知道我们需要在UI线程中运行特定的代码,并且我们有一种特定的方法来处理在该UI线程上引发的异常(BeginInvoke没有阻塞,因此不会传输异常)。我们如何才能创建一个方法,使同样的事情,但更简单,像这样:
this.BeginInvoke(new MethodInvoker(() =>
{
try
{
//code
}
catch(Exception ex)
{
HandleException(ex);
}
}
RunOnUIThread(MyMethod);
RunOnUIThread将包含与此代码中第一个示例相同或更少的代码
有可能创建这样的方法吗?如果是这样的话,怎么做?公共静态void invokeControlion(t cont,Action Action)其中t:Control
public static void InvokeControlAction<t>(t cont, Action<t> action) where t : Control
{
if (cont.InvokeRequired)
{ cont.Invoke(new Action<t, Action<t>>(InvokeControlAction),
new object[] { cont, action }); }
else
{ action(cont); }
}
{
如果(续调用要求)
{cont.Invoke(新操作(InvokeControlAction),
新对象[]{cont,action};}
其他的
{行动(续);}
}
您可以编写一些很好的扩展方法,如下所示
public static class ControlExtension
{
public static IAsyncResult BeginInvokeWithExceptionHandling(this Control control, Action method, Action<Exception> exceptionHandler)
{
if (control == null) throw new ArgumentNullException("control");
if (method == null) throw new ArgumentNullException("method");
if (exceptionHandler == null) throw new ArgumentNullException("exceptionHandler");
return control.BeginInvoke(new MethodInvoker(() =>
{
try
{
method();
}
catch (Exception ex)
{
exceptionHandler(ex);
}
}));
}
public static IAsyncResult BeginInvokeWithExceptionHandling<T>(this Control control, Delegate method, Action<Exception> exceptionHandler, params object[] args)
{
if (control == null) throw new ArgumentNullException("control");
if (method == null) throw new ArgumentNullException("method");
if (exceptionHandler == null) throw new ArgumentNullException("exceptionHandler");
return control.BeginInvoke(new MethodInvoker(() =>
{
try
{
method.DynamicInvoke(args);
}
catch (Exception ex)
{
exceptionHandler(ex);
}
}));
}
}
注意:由于
Delegate.DynamicInvoke
这可能会稍差一些,您可以使用强类型委托修复它。还值得注意的是,control.BeginInvoke
也在内部使用Delegate.DynamicInvoke
,如果它找不到委托类型是什么。我根据Sriram的建议结束了upp:
public static void SendToUIThread(Action method, bool UseExceptionHandling = true)
{
if (method == null)
throw new ArgumentNullException("method is missing");
_threadSyncContext.Send(new SendOrPostCallback(delegate(object state)
{
if (UseExceptionHandling)
{
try
{
method();
}
catch (Exception ex)
{
ErrorController.Instance.LogAndDisplayException(ex, true);
}
}
else
method();
}), null);
}
public static void PostOnUIThread(this Control control, Action method, bool UseExceptionHandling = true)
{
if (method == null)
throw new ArgumentNullException("method is missing");
if (control.InvokeRequired)
PostOnUIThread(method, UseExceptionHandling);
else
{
if (UseExceptionHandling)
{
try { method(); }
catch (Exception ex) { ErrorController.Instance.LogAndDisplayException(ex, true); }
}
else
method();
}
}
谢谢,但是代码还是太多了,我只想调用RunOnUIThread(MyMethod);您当然可以这样做,但是当出现异常时您想做什么呢?我需要运行与第一个示例中相同的代码。因此,请尝试/catch并在catch中处理异常(此案例记录到数据库)@Banshee更新了我的答案,使其代码更少。很好,非常感谢!我会尽快尝试的。谢谢,但是代码还是太多了,我只想调用RunOnUIThread(MyMethod);