发布中的多线程错误,代码优化已开启

问题描述 投票:0回答:1

单击按钮时,我将从主窗口打开一个新的子窗口。加载后,子窗口将使用鼠标光标位置跟踪器启动任务。子窗口关闭时,信号变量

stopMouseTracker
设置为
true
并且任务中的无限循环应该终止。下面的代码在调试和发布中都适用,无需代码优化。但是,当我在启用代码优化的发布中运行代码时,子窗口在我尝试关闭它后冻结。什么可能导致问题?

主窗口:

public MainWindow()
{
    InitializeComponent();
}

private void button_Click(object sender, RoutedEventArgs e)
{
    SubWindow subWindow = new();

    subWindow.ShowDialog();
}

子窗口:

bool mouseTrackerOn = false;
bool stopMouseTracker = false;

public SubWindow()
{
    InitializeComponent();

    StartMouseTracker();
}

private void StartMouseTracker()
{
    mouseTrackerOn = true;

    Task.Factory.StartNew(() =>
    {
        while (!stopMouseTracker)
        {
            var p = System.Windows.Forms.Cursor.Position;
            
            // Write cursor coordinates to text box tbXY
            tbXY.Dispatcher.BeginInvoke(() => tbXY.Text = $"{p.X} {p.Y}");

            Thread.Sleep(1);
        }

        mouseTrackerOn = false;
    });
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    stopMouseTracker = true;

    // This blocks the thread completely in Release with code optimization on
    while (mouseTrackerOn) ;
}
c# wpf .net-core optimization task
1个回答
0
投票

您有一个非锁定变量,您正在从另一个线程检查该变量。虽然

volatile
Interlocked.Read
等可以解决这个问题,但你并不需要所有这些搞乱任务和
Dispatcher
无论如何。

只需使用

CancellationToken
中止循环,然后使用
async
将循环置于 UI 线程上。

private CancellationTokenSource _stopMouseTracker = new();

public SubWindow()
{
    InitializeComponent();
    StartMouseTracker(_stopMouseTracker.Token);
}

private async Task StartMouseTracker(CancellationToken cancellationToken)
{
    try
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            var p = System.Windows.Forms.Cursor.Position;
            // Write cursor coordinates to text box tbXY
            tbXY.Text = $"{p.X} {p.Y}";
            await Task.Delay(1, cancellationToken);
        }
    }
    catch
    { //
    }
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    stopMouseTracker.Cancel();
}
© www.soinside.com 2019 - 2024. All rights reserved.