在我维护一个严重违反winforms中的跨线程更新规则的旧应用程序的过程中,我创建了以下扩展方法,以便在我发现它们时快速修复非法调用:
/// <summary>
/// Execute a method on the control's owning thread.
/// </summary>
/// <param name="uiElement">The control that is being updated.</param>
/// <param name="updater">The method that updates uiElement.</param>
/// <param name="forceSynchronous">True to force synchronous execution of
/// updater. False to allow asynchronous execution if the call is marshalled
/// from a non-GUI thread. If the method is called on the GUI thread,
/// execution is always synchronous.</param>
public static void SafeInvoke(this Control uiElement, Action updater, bool forceSynchronous)
{
if …Run Code Online (Sandbox Code Playgroud) 我正在制作Windows窗体应用程序.我有一张表格.我想在单击按钮时从原始表单在运行时打开一个新表单.然后以编程方式关闭这个新表单(2,3秒后),但是从gui主线程以外的线程中关闭.
我想从我的后台工作人员访问我的GUI上的列表框中的选择.没有任何其他更改尝试这样做会抛出此错误
Cross-thread Operation Not Valid: Control '_ListBox1' accessed from a thread other than the thread it was created on
Run Code Online (Sandbox Code Playgroud)
我看到避免这种情况的选项是使用Invoke以下语法,但是这个.Net 4(或更高)是否可以接受?
var selectedItems = (IList)this.Invoke(new Func<IList>(() => Listbox1.SelectedItems.Cast<object>().ToList()));
Run Code Online (Sandbox Code Playgroud)
为了更清楚地了解这是我想从我的后台工作者访问列表框项目的方式
namespace clown
{
public partial class Form1 : Form1
{
public Form1()
{
ListBox1.Items.Add("Firefly");
ListBox1.Items.Add("Hellfire");
}
private void btn1234_Click()
{
backgroundworker1.RunWorkerAsync();
}
private void backgroundworker1_DoWork(object sender, DoWorkEventArgs e)
{
//Long Running Process taking place here
//then we hit this
if (ListBox1.SelectedItems.Contains("Firefly")) { //take this course }
if …Run Code Online (Sandbox Code Playgroud) 我试图将调度程序包装在一个线程中.但结果并不是我所期待的.我该如何解决这个问题?
public void Start()
{
ThreadStart ts = inner;
Thread wrapper = new Thread(ts);
wrapper.Start();
}
private void inner()
{
_Runner.Dispatcher.Invoke(_Runner.Action, DispatcherPriority.Normal);
}
Run Code Online (Sandbox Code Playgroud)