Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Begin Invoke未运行_C#_Wpf_Multithreading_Invoke_Dispatcher - Fatal编程技术网

C# Begin Invoke未运行

C# Begin Invoke未运行,c#,wpf,multithreading,invoke,dispatcher,C#,Wpf,Multithreading,Invoke,Dispatcher,Im使用System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Input,新操作(()=>…)刷新wpf图形 它在我的另一个函数中非常有效,但在我的SQL delete函数中它不会被触发/执行 我用System.Windows.Forms.Application.DoEvents();尝试了它,但它没有任何作用 Set_Loading_Changed() { System.Windows.

Im使用
System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Input,新操作(()=>…
)刷新wpf图形

它在我的另一个函数中非常有效,但在我的SQL delete函数中它不会被触发/执行

我用
System.Windows.Forms.Application.DoEvents();
尝试了它,但它没有任何作用

Set_Loading_Changed()
{
    System.Windows.Application.Current.Dispatcher.BeginInvoke(
        DispatcherPriority.Input, 
        new Action(() =>
        {
            if (BLoading)
            {
                DataGrid_Anzeige.IsEnabled = false;

                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
            }
            else
            {
                DataGrid_Anzeige.IsEnabled = true;
        
                Mouse.OverrideCursor = null;
            }
        }));
}
Btn_Remove()
{
...
设置_加载_更改();
使用(OLEDB连接ODC=新OLEDB连接(“…”)
{
foreach(DataGrid_Anzeige.SelectedItems.OfType()中的变量selectedRow)
{
sSQL_语句=“…”;
ODC.Open();
OleDbCommand ODCmd=新的OleDbCommand(sSQL_语句,ODC);
ODCmd.ExecuteNonQuery();
ODC.Close();
编辑:

我插入了我的
Set\u Load\u Changed()
函数的完整部分,希望你能从这些信息中得到线索


我主要是在我的搜索线程(
Task.Factory.StartNew(()=>{…}));
)中使用它,所以它必须是
DispatcherPriority.Input

如果你想在
Set\u Loading\u Changed()
中执行任何操作,在连接到数据库之前,你应该调用
Invoke
而不是
BeginInvoke

Set_Loading_Changed()
{
    System.Windows.Application.Current.Dispatcher.Invoke(...);
}

由于误解了WPF线程系统,您遇到了一个常见问题。WPF的结构方式是,一个线程用于程序运行和修改UI,通常称为UI线程,另一个线程用于自动呈现UI,通常称为呈现或合成正在加载线程。

这里您需要知道的关键点是,如果您在
BeginInvoke()
之后立即使用大型操作(如数据库读取或大型计算)暂停UI线程,那么您将阻止UI线程运行这些命令,直到您允许它调用下一个操作。
BeginInvoke()
只需将下一次允许调度程序执行的操作排队-调度程序不会中断当前正在执行的操作。将优先级设置为
Input
可确保它将在其他优先级较低的工作之前处理,但仍不会导致它中断您当前的方法。
如果您改为调用
Invoke()
,则会中断您的工作,要求调度程序执行操作,然后在操作完成后返回您正在执行的操作。

虽然这比您当前获得的行为更可取,但这不是您打算使用dispatcher的方式,并且在完成长操作时仍会导致您的应用程序显示为“冻结”。要避免这种情况,最简单的方法是在任务中运行长操作,使用async/Wait关键字和Task Parallel Libra里。

斯蒂芬·克利里(Stephen Cleary)有一个很好的博客,涵盖了许多与此相关的主题。他的介绍性文章(可以追溯到关键字的介绍)是。 如果你在这个领域有更多的问题,我会鼓励你浏览他的博客——他是解释这个领域的主要专家之一,涵盖了你遇到的大部分问题


进一步阅读:


不幸的是,在WPF中更改光标并不像在WinForms中那样简单。我记得我自己也在努力解决它,直到我偶然发现了以下解决方案。我自己并没有想到这一点,我会尝试找到来源,以便在适当的时候给予信任

using System;
using System.Collections.Generic;
using System.Windows.Input;

namespace MyNamespace
{
    public class OverrideCursor : IDisposable
    {
        static Stack<Cursor> s_Stack = new Stack<Cursor>();

        public OverrideCursor(Cursor changeToCursor = null)
        {
            if (changeToCursor == null)
                changeToCursor = Cursors.Wait;

            s_Stack.Push(changeToCursor);

            if (Mouse.OverrideCursor != changeToCursor)
                Mouse.OverrideCursor = changeToCursor;
        }

        public void Dispose()
        {
            s_Stack.Pop();
            var cursor = _stack.Count > 0 ? _stack.Peek() : null;
            if (Mouse.OverrideCursor != cursor)
                Mouse.OverrideCursor = cursor;

        }
    }
}
这将通过将光标作为构造函数的参数传递,将光标更改为您想要的任何内容,或者不使用
光标。默认情况下,等待
。
对于执行放置在using块内的任何代码所需的时间,光标将在之后变回正常状态。
您也可以在不使用using块的情况下启动类的对象来无限期地设置它,但在完成时不要忘记调用
Dispose()


编辑:来源:

你在BeginInvoke里面做什么?你怎么知道它没有运行?试着将优先级更改为正常。@mm8因为它在另外两个需要输入优先级的函数中运行良好。给我一点时间,我编辑这篇文章。你想更改设置吗要在SQL之前执行,或者您的问题是什么?请尝试调用Invoke而不是BeginInvoke。这应该可以按编写的方式工作。我猜您是在代码中的其他位置重置光标,或者在应用光标更新之前继续阻止UI线程。请尝试调用
Mouse.UpdateCursor()
设置
OverrideCursor
后立即执行。如果这没有帮助,请在代码中找到覆盖光标的每个位置,设置断点,然后查看是否在某个地方意外清除光标。
using System;
using System.Collections.Generic;
using System.Windows.Input;

namespace MyNamespace
{
    public class OverrideCursor : IDisposable
    {
        static Stack<Cursor> s_Stack = new Stack<Cursor>();

        public OverrideCursor(Cursor changeToCursor = null)
        {
            if (changeToCursor == null)
                changeToCursor = Cursors.Wait;

            s_Stack.Push(changeToCursor);

            if (Mouse.OverrideCursor != changeToCursor)
                Mouse.OverrideCursor = changeToCursor;
        }

        public void Dispose()
        {
            s_Stack.Pop();
            var cursor = _stack.Count > 0 ? _stack.Peek() : null;
            if (Mouse.OverrideCursor != cursor)
                Mouse.OverrideCursor = cursor;

        }
    }
}
using (new OverrideCursor())
{
    //your code 
}