Delphi Firemonkey在主线程 异步调用函数(延迟调用)

先看下面的FMX.Layouts.pas中一段代码

procedure TCustomScrollBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Single);
begin
  FMouseEvents := True;
  inherited;
  if (Button = TMouseButton.mbLeft) then
  begin
    MousePosToAni(X, Y);
    AniMouseDown(ssTouch in Shift, X, Y);
  end;
end;

在执行Inherited;这行时可能会调用控件的OnDblClick事件,如果此时在OnDblClick中将Form或控件释放了,后面调用MousePosToAni可能就会造成内存访问异常

因此最好能够在UI线程(主线程)中执行MouseDown完全后,再调用Form或控件的释放,如下面

procedure TForm1.OnListBox1Item1DblClick(Sender:TObject);
begin
  ....//处理一些事情
  AsyncCallInUIThread(
    procedure
    begin
      Self.DisposeOf; //延迟释放,防止内存访问异常
    end);
end;

  

下面是AsyncCallInUIThread的实现:

procedure AsyncCallInUIThread(Proc: TProc);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      Sleep(0);
      TThread.Synchronize(nil,
        procedure
        begin
          Proc;
        end);
    end).Start;
end;

  

时间: 2024-09-30 18:36:33

Delphi Firemonkey在主线程 异步调用函数(延迟调用)的相关文章

Python_Tips[2] -> 函数延迟调用与变量值

函数延迟调用与变量值 在一个循环中定义了函数f但是并未对其进行调用,在循环结束后调用,此时i值为3故最终3个函数输出均为9. 1 import dis 2 3 def count(): 4 fs = [] 5 for i in range(1,4): 6 def f(): 7 return i*i 8 fs.append(f) 9 return fs 10 11 def run(): 12 f1, f2, f3 = count() 13 # When the function called, t

如何让 Qt 的程序使用 Sleep(主线程没有Sleep函数,但线程可用自带的保护函数Sleep)

熟悉的陌生人 Qt 是事件驱动的,所以当你用Qt的时候,几乎时时刻刻和 QEventLoop 打交道.,只是你可能没有意识到: QCoreApplicaton::exec() QApplication::exec() QDialog::exec() QThread::exec() QDrag::exec() QMenu::exec() ... 在前面列出的这些常见函数的背后,都有各自的QEventLoop,可能是我们很少有机会想到自己显式使用QEventLoop的缘故吧,对这个类似乎总是有些陌生

全局异步和主线程异步区别、改变PlaceHolder颜色、解决键盘弹起挡住文本框问题

1.全局异步执行耗时任务 dispatch_async(dispatch_get_global_queue(0, 0), ^{ }); 2.主线程异步刷新UI dispatch_async(dispatch_get_main_queue(), ^{ }); 3.改变PlaceHolder的颜色 [username_text setValue:[UIColor colorWithRed:1 green:1 blue:1 alpha:0.5] forKeyPath:@"_placeholderLab

FastReport调用Delphi中的人民币大写转换自定义函数

FastReport调用Delphi中的人民币大写转换自定义函数 FastReport调用Delphi中的人民币大写转换自定义函数 function TJzpzEdit1.MoneyCn(mmje: Double): string; const s1: string = '零壹贰叁肆伍陆柒捌玖'; s2: string = '分角元拾佰仟万拾佰仟亿拾佰仟万'; function StrTran(const S, s1, s2: string): string; begin Result := S

[转载]DllMain中不当操作导致死锁问题的分析--进程对DllMain函数的调用规律的研究和分析

(转载于breaksoftware的csdn博客) 不知道大家是否思考过一个过程:系统试图运行我们写的程序,它是怎么知道程序起始位置的?很多同学想到,我们在编写程序时有个函数,类似Main这样的名字.是的!这就是系统给我们提供的控制程序最开始的地方(注意这儿是提供给我们的,而实际有比这个还要靠前的main).于是看到DllMain就可以想到它是干嘛的了:Dll的入口点函数.那何时调用这个函数的呢?以及各种调用场景都传给了它什么参数呢? 进程对DLL的载入卸载,以及新线程的创建和退出都会导致对Dl

主线程退出问题

主线程如果正常退出(即执行return返回),那么整个进程中所有的其他线程都会被清理: 如果主线程内执行ExitThread函数进行退出,那么主线程会执行退出,但是其他的线程不会被清理,而会一直执行到正常退出为止. #include <iostream> #include <process.h> #include <Windows.h> using namespace std; UINT WINAPI ThreadProc(LPVOID pParam) { int p

python两个类之间变量和函数的调用

1.class_a() class_b() 2.class_b使用class_a中的变量和函数 3.变量class_a中:class_a.num=... 函数class_b中:先实例化class_a(如果在class_a中有初始化,则此时还会初始化一次,为避免二次初始化可以把class_a中的初始化不写为初始化函数),  然后调用函数 在调用函数中再调用的函数里用到的class_a的变量,也必须在class_a中:class_a.num=...这种形式.

Delphi主线程重入而导致程序卡死的解决方案

Delphi的线程可以通过调用AThread.Synchronize(AProc),可以将Proc放入主线程中同步运行,此时AThread将挂起,直到主线程执行完AProc. 如果有BThread,调用了BThread.Synchronize(BProc),而BProc中释放了AThread procedure TBThread.BProc begin AThread.Terminate; AThread.WaitFor; AThread.Free; end; 此时我们的程序将会卡死,下面的代码

C# 线程调用主线程中的控件

由于项目的需要,最近几天一直在做串口和数据库.由于C#使用的时间不长,所以在编写代码和调试的过程中总是遇到意想不到的问题,比如在使用串口接收数据的时候,在接收数据事件中想把接收的数据放入一个textbox作显示,但是明明非常简单的代码,在编译的时候总是提示有错误.后来查看网上资料,才知道C#还有委托,匿名等等之类的新东西.下面我就把我这几天的经验和大家分享一下.这次就主要说说委托和匿名方法,以后在说说串口使用方面的经验. 先说一下委托的基本概念,委托是一种引用型的数据类型,其实它的概念和C语言的