如何处理view上的子线程异常?
How to handle child thread exception on view?
我有一个小的 MVC 模式应用程序,它使用随机数据创建 UDP 数据包,并不断发送它
主视图包含控制器:
public partial class MainForm : Form
{
private MainController controller;
public MainForm(MainController c)
{
controller = c;
InitializeComponent();
}
//...
}
主按钮单击事件调用最终将启动仿真的方法。我将它包裹在一个 try-cath 块中,这样我就可以在视图中显示任何异常
public partial class MainForm : Form
{
//...
private void btnInitiate_Click(object sender, EventArgs e)
{
try
{
controller.initiateEmulation(txtData.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class MainController:IMainController
{
private Emulator model;
public void initiateEmulation(string data)
{
model = new Emulator(data);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public Emulator(string data)
{
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
//CREATES SOCKET
while (true)
{
//SENDS RANDOMIZED DATA
}
}
}
问题是,我的 try-catch 块只捕获主线程中发生的异常
如何处理 emulatorThread 中的异常,以便我可以在视图中显示它们,就像在主线程中一样?
您可以通过几种有趣的方式来处理这类事情,不太确定这些是否是"best practices",如果您不熟悉这些概念,您可能需要做一些研究
首先是代表:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data", HandleEmulatorException);
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public OnException OnError;
public delegate void OnException(Exception e);
public Emulator(string data, OnException onError)
{
OnError = onError;
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
这里我给模拟器一个委托,它可以在每次发生异常时调用它,你也可以用 functions/actions:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data", HandleEmulatorException);
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public Action<Exception> OnError;
public Emulator(string data, Action<Exception> onError)
{
OnError = onError;
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
相同的概念,但您不必声明委托,事件是另一个:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data");
_emulator.OnError += HandleEmulatorException;
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public event OnException OnError;
public delegate void OnException(Exception e);
public Emulator(string data)
{
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
同样是类似的概念,但您不必传入委托,但必须声明一个。
希望对您有所帮助
我有一个小的 MVC 模式应用程序,它使用随机数据创建 UDP 数据包,并不断发送它
主视图包含控制器:
public partial class MainForm : Form
{
private MainController controller;
public MainForm(MainController c)
{
controller = c;
InitializeComponent();
}
//...
}
主按钮单击事件调用最终将启动仿真的方法。我将它包裹在一个 try-cath 块中,这样我就可以在视图中显示任何异常
public partial class MainForm : Form
{
//...
private void btnInitiate_Click(object sender, EventArgs e)
{
try
{
controller.initiateEmulation(txtData.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.StackTrace, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class MainController:IMainController
{
private Emulator model;
public void initiateEmulation(string data)
{
model = new Emulator(data);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public Emulator(string data)
{
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
//CREATES SOCKET
while (true)
{
//SENDS RANDOMIZED DATA
}
}
}
问题是,我的 try-catch 块只捕获主线程中发生的异常
如何处理 emulatorThread 中的异常,以便我可以在视图中显示它们,就像在主线程中一样?
您可以通过几种有趣的方式来处理这类事情,不太确定这些是否是"best practices",如果您不熟悉这些概念,您可能需要做一些研究
首先是代表:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data", HandleEmulatorException);
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public OnException OnError;
public delegate void OnException(Exception e);
public Emulator(string data, OnException onError)
{
OnError = onError;
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
这里我给模拟器一个委托,它可以在每次发生异常时调用它,你也可以用 functions/actions:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data", HandleEmulatorException);
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public Action<Exception> OnError;
public Emulator(string data, Action<Exception> onError)
{
OnError = onError;
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
相同的概念,但您不必声明委托,事件是另一个:
public class MainForm
{
private Emulator _emulator;
public MainForm()
{
_emulator = new Emulator("data");
_emulator.OnError += HandleEmulatorException;
}
public void Render()
{
// Do other stuff
}
public void HandleEmulatorException(Exception e)
{
Console.WriteLine(e.Message);
}
}
public class Emulator
{
private Thread emulatorThread;
public String data;
public event OnException OnError;
public delegate void OnException(Exception e);
public Emulator(string data)
{
this.data = data;
emulatorThread = new Thread(Emulate);
emulatorThread.Start();
}
private void Emulate()
{
while (true)
{
try
{
throw new Exception("Exception was thrown");
}
catch (Exception e)
{
OnError(e);
}
}
}
}
同样是类似的概念,但您不必传入委托,但必须声明一个。
希望对您有所帮助