Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.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# 在单独的线程中显示MessageBox并自动关闭此线程_C#_Wpf_Multithreading - Fatal编程技术网

C# 在单独的线程中显示MessageBox并自动关闭此线程

C# 在单独的线程中显示MessageBox并自动关闭此线程,c#,wpf,multithreading,C#,Wpf,Multithreading,我使用WPF应用程序和遗留代码。有一个应用程序用于分配液体。每次给药时,应检查是否用分配器更换了杯子,如果没有,则显示需要更换杯子的信息。分配器有一个换杯传感器。如果杯子换了,我需要自动关闭MessageBox。为此,运行两个线程。第一个是MessageBox,另一个是调查流程分配器。这是代码: public bool CheckChangeCupInThread() { if (_dispenser.Status.CupChanged == DispenserEnums.CupChan

我使用WPF应用程序和遗留代码。有一个应用程序用于分配液体。每次给药时,应检查是否用分配器更换了杯子,如果没有,则显示需要更换杯子的信息。分配器有一个换杯传感器。如果杯子换了,我需要自动关闭MessageBox。为此,运行两个线程。第一个是MessageBox,另一个是调查流程分配器。这是代码:

public bool CheckChangeCupInThread()
{
    if (_dispenser.Status.CupChanged == DispenserEnums.CupChanged.False)
    {
        var cupFormThread = new ThreadStart(CupWaitChangeForm);
        var cupFormWaiter = new Thread(cupFormThread) {IsBackground = true};
        cupFormWaiter.SetApartmentState(ApartmentState.STA);

        var cupThread = new ThreadStart(WaitForCupChange);
        var cupWaiter = new Thread(cupThread) {IsBackground = true};
        cupWaiter.SetApartmentState(ApartmentState.STA);

        cupFormWaiter.Start();
        cupWaiter.Start();

        do
        {
            //Wait for Cup to be changed or Cancel
        } while (cupFormWaiter.IsAlive && cupWaiter.IsAlive);

        var watch = new Stopwatch();
        watch.Start();

        if (cupFormWaiter.IsAlive)
        {
            cupFormWaiter.Abort();
        }
        if (cupWaiter.IsAlive)
        {
            _dispenser.SurveillanceWorker.Continue = false;
            cupWaiter.Join(200);
            return false;
        }
        watch.Stop();
    }
    return true;
}

private void WaitForCupChange()
{
    do
    {
        _dispenser.GetStatus();
    } while (_dispenser.Status.CupChanged == DispenserEnums.CupChanged.False);
}

private void CupWaitChangeForm()
{
    MessageBox.Show("Change please the cup", "Cup сhange", MessageBoxButtons.Cancel);
}

前面的代码已经在一个包含4000多行代码的大型类中使用。我进行了重构,并将这段代码放在一个单独的类中。现在,在改变了cup之后,程序崩溃了,不是在这个地方,而是在代码的某个地方。在Windows10中使用应用程序时经常发生的最有趣的事情是,这在Windows7中几乎没有发生。我是多线程的新手,不懂如何解决这个问题。我尝试了任务和令牌,但令牌无法关闭MessageBox线程,直到按下按钮。谢谢,我解决了一个问题。现在,如果Task1完成,MessageBox将关闭。或者关闭MessageBox,然后终止Task1

internal class Program
{
    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;

    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    private static void Main(string[] args)
    {
        Action<object> action = (object obj) =>
        {
            int i = 0;
            do
            {
                Thread.Sleep(500);
                i++;
            } while (i < 10);
            Console.WriteLine("t1 has been finished");
        };

        Action<object> action1 = (object obj) =>
        {
            DialogResult result = DialogResult.OK;
            do
            {
                result = MessageBox.Show("This is task2", "Task2", MessageBoxButtons.OKCancel);
            } while (result != DialogResult.Cancel);
            Console.WriteLine("t2 has been finished");
        };

        var tasks = new Task[2];
        var source1 = new CancellationTokenSource();
        var token1 = source1.Token;
        Task t1 = new Task(action, "alpha", token1);
        tasks[0] = t1;
        Task t2 = new Task(action1, "betha");
        tasks[1] = t2;

        t1.Start();
        Console.WriteLine("t1 has been launched. (Main Thread={0})",
            Thread.CurrentThread.ManagedThreadId);

        t2.Start();
        Console.WriteLine("t2 has been launched. (Main Thread={0})",
            Thread.CurrentThread.ManagedThreadId);

        try
        {
            int index = Task.WaitAny(tasks);
            if (t1.Status == TaskStatus.Running)
                source1.Cancel();
            if (t2.Status == TaskStatus.Running)
                CloseMessage();
            Console.WriteLine("Task #{0} completed first.\n", tasks[index].Id);
            Console.WriteLine("Status of all tasks:");
            foreach (var t in tasks)
                Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status);
        }
        catch (AggregateException)
        {
            Console.WriteLine("An exception occurred.");
        }
        Console.ReadLine();
    }

    private static void CloseMessage()
    {
        int window = FindWindow(null, "Task2");
        if (window != 0)
            SendMessage(window, WM_SYSCOMMAND, SC_CLOSE, 0);
    }
}
内部类程序
{
public const int WM_SYSCOMMAND=0x0112;
公共常数int SC_CLOSE=0xF060;
[DllImport(“user32.dll”)]
公共静态外部程序int FindWindow(字符串lpClassName,字符串lpWindowName);
[DllImport(“user32.dll”)]
公共静态外部int SendMessage(int hWnd、uint Msg、int wParam、int lParam);
私有静态void Main(字符串[]args)
{
动作动作=(对象对象对象)=>
{
int i=0;
做
{
睡眠(500);
i++;
}而(i<10);
Console.WriteLine(“t1已完成”);
};
动作动作1=(对象对象对象)=>
{
DialogResult=DialogResult.OK;
做
{
结果=MessageBox.Show(“这是task2”,“task2”,MessageBoxButtons.OKCancel);
}while(result!=DialogResult.Cancel);
Console.WriteLine(“t2已完成”);
};
var tasks=新任务[2];
var source1=新的CancellationTokenSource();
var token1=source1.Token;
任务t1=新任务(动作“alpha”,标记1);
任务[0]=t1;
任务t2=新任务(行动1,“betha”);
任务[1]=t2;
t1.Start();
WriteLine(“t1已启动。(主线程={0})”,
Thread.CurrentThread.ManagedThreadId);
t2.Start();
WriteLine(“t2已启动。(主线程={0})”,
Thread.CurrentThread.ManagedThreadId);
尝试
{
int index=Task.WaitAny(任务);
if(t1.Status==TaskStatus.Running)
source1.Cancel();
if(t2.Status==TaskStatus.Running)
CloseMessage();
WriteLine(“任务{0}首先完成。\n”,任务[index].Id);
Console.WriteLine(“所有任务的状态:”);
foreach(任务中的var t)
WriteLine(“任务{0}:{1}”,t.Id,t.Status);
}
捕获(聚合异常)
{
WriteLine(“发生异常”);
}
Console.ReadLine();
}
私有静态void CloseMessage()
{
int window=FindWindow(null,“Task2”);
如果(窗口!=0)
SendMessage(窗口,WM_SYSCOMMAND,SC_CLOSE,0);
}
}

如果你只想让另一个线程在循环中旋转直到完成,那么创建另一个线程是没有意义的。我想我需要两个线程,因为我有两个事件——或者一个杯子被更改了,或者MessageBox中的“取消”按钮被点击了。我怎么看这两个?你不需要任何额外的线程。您应该对代码进行结构化,使其是异步的,并且您会收到更改通知,而不是坐在CPU上煮鸡蛋的循环中,而不是将其用于有效率的事情。