【问题标题】:C# access ref variable passed to window, from another window functionC# 访问传递给窗口的 ref 变量,从另一个窗口函数
【发布时间】:2021-11-20 11:40:05
【问题描述】:
public int stop = 0;
public void main()
{
    Thread thrDoStuff = new Thread(()=> dostuff(ref stop));
    testWindow window = new testWindow(ref stop);
}

public void dostuff(ref int stop)
{
    while (true)
    {
        if (stop != 0)
        {
            break;
        }
    }
    //exit from loop and do other stuff
} 

stop 是我想在函数dostuff 中使用的变量,以了解何时退出循环。 窗口是一个窗口......我希望能够将值更改为stop 变量。 例如从按钮单击,或从窗口启动的线程。

这里是窗口代码:

public readonly DispatcherTimer Start = new DispatcherTimer();
public testWindow (ref int stop )
{
    InitializeComponent();
    //i know that if i change the stop value here, the change will be also visible from  dostuff function. but i want to change the stop value from a botton click for example
        
    Start.Interval = TimeSpan.FromMilliseconds(100);
    Start.Tick += workloop;
    Start.IsEnabled = true;
 }

private void buttonClick(object sender, RoutedEventArgs e)
{
    //i would like to change value to sotp variable here, and the change has to be reflected to dostuff function
}

private void workloop(object sender, EventArgs e)
{
    //i want this function to be run only once
    Start.IsEnabled = false;
    
    //i would like to change value to stop function also from here
}     

我该怎么做??

【问题讨论】:

  • 您重新发明的任何原因(有点,没有实际实现类型)CancellationToken(Source)?
  • 感谢您的输入,我不知道 CancellationToken。我会花一些时间阅读文档和测试。

标签: c# multithreading ref


【解决方案1】:

这个问题有几个内置的解决方案,所以你不需要像Damien_The_Unbeliever所指出的那样重新发明轮子。

在Tasks 之前,我们通常为此使用ManualResetEventSlim。

static void Main()
{
    var cancellationSignal = new ManualResetEventSlim();
    Task.Run(async () =>
    {
        await Task.Delay(200);
        cancellationSignal.Set();
    });

    for (int i = 0; i < 100; i++)
    {
        if (cancellationSignal.IsSet)
        {
            cancellationSignal.Dispose();
            break;
        }
                    
        Thread.Sleep(10);
        Console.WriteLine(i);
    }
    Console.WriteLine("Finished");
}

如您所见,这个类也可以用于其他类型的信号。

对于Tasks,我们有一个专门用于取消的类,称为CancellationTokenSource:

static void Main()
{
    var cancellationSignal = new CancellationTokenSource();
    Task.Run(async () =>
    {
        await Task.Delay(200);
        cancellationSignal.Cancel();
    });

    for (int i = 0; i < 100; i++)
    {
        if (cancellationSignal.IsCancellationRequested)
        {
            cancellationSignal.Dispose();
            break;
        }
                    
        Thread.Sleep(10);
        Console.WriteLine(i);
    }
    Console.WriteLine("Finished");
}

请记住,这两个类都实现了IDisposable,因此我们必须确保在使用后处理它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2016-10-11
    相关资源
    最近更新 更多