Чтобы скомпилировать этот код, выполните следующие действия. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Чтобы скомпилировать этот код, выполните следующие действия.



1. Создайте в Visual Studio новый проект приложения Windows C# и назовите его WinSound.

2. Скопируйте приведенный выше код и вставьте его поверх содержимого файла Form1.cs.

3. Скопируйте следующий код и вставьте его в файл Form1.Designer.cs в метод InitializeComponent() после уже имеющегося там кода.

ß----

 

 

4. Скомпилируйте и запустите код.

 


PlaySound

The PlaySound function plays a sound specified by the given filename, resource, or system event. (A system event may be associated with a sound in the registry or in the WIN.INI file.)

BOOL PlaySound(

LPCSTR pszSound,

HMODULE hmod,

DWORD fdwSound

);

Parameters

pszSound

A string that specifies the sound to play. The maximum length, including the null terminator, is 256 characters. If this parameter is NULL, any currently playing waveform sound is stopped. To stop a non-waveform sound, specify SND_PURGE in the fdwSound parameter.

Three flags in fdwSound (SND_ALIAS, SND_FILENAME, and SND_RESOURCE) determine whether the name is interpreted as an alias for a system event, a filename, or a resource identifier. If none of these flags are specified, PlaySound searches the registry or the WIN.INI file for an association with the specified sound name. If an association is found, the sound event is played. If no association is found in the registry, the name is interpreted as a filename.

hmod

Handle to the executable file that contains the resource to be loaded. This parameter must be NULL unless SND_RESOURCE is specified in fdwSound.

fdwSound

Flags for playing the sound. The following values are defined.

 


 


 

Value Meaning
SND_APPLICATION The sound is played using an application-specific association.
SND_ALIAS The pszSound parameter is a system-event alias in the registry or the WIN.INI file. Do not use with either SND_FILENAME or SND_RESOURCE.
SND_ALIAS_ID The pszSound parameter is a predefined sound identifier.
SND_ASYNC The sound is played asynchronously and PlaySound returns immediately after beginning the sound. To terminate an asynchronously played waveform sound, call PlaySound with pszSound set to NULL.
SND_FILENAME The pszSound parameter is a filename.
SND_LOOP The sound plays repeatedly until PlaySound is called again with the pszSound parameter set to NULL. You must also specify the SND_ASYNC flag to indicate an asynchronous sound event.
SND_MEMORY A sound event's file is loaded in RAM. The parameter specified by pszSound must point to an image of a sound in memory.
SND_NODEFAULT No default sound event is used. If the sound cannot be found, PlaySound returns silently without playing the default sound.
SND_NOSTOP The specified sound event will yield to another sound event that is already playing. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound. If this flag is not specified, PlaySound attempts to stop the currently playing sound so that the device can be used to play the new sound.
SND_NOWAIT If the driver is busy, return immediately without playing the sound.

 

 

SND_PURGE Sounds are to be stopped for the calling task. If pszSound is not NULL, all instances of the specified sound are stopped. If pszSound is NULL, all sounds that are playing on behalf of the calling task are stopped. You must also specify the instance handle to stop SND_RESOURCE events.
SND_RESOURCE The pszSound parameter is a resource identifier; hmod must identify the instance that contains the resource.
SND_SYNC Synchronous playback of a sound event. PlaySound returns after the sound event completes.
SND_SYSTEM Requires Windows Vista or later. If this flag is set, the sound is assigned to the audio session for system notification sounds. The system volume-control program (SndVol) displays a volume slider that controls system notification sounds. Setting this flag puts the sound under the control of that volume slider. If this flag is not set, the sound is assigned to the default audio session for the application's process. For more information, see the documentation for the Core Audio APIs in the Windows SDK.

Return Values

Returns TRUE if successful or FALSE otherwise.

Remarks

The sound specified by pszSound must fit into available physical memory and be playable by an installed waveform-audio device driver. PlaySound searches the following directories for sound files: the current directory; the Windows directory; the Windows system directory; directories listed in the PATH environment variable; and the list of directories mapped in a network. For more information about the directory search order, see the documentation for the OpenFile function.

If it cannot find the specified sound, PlaySound uses the default system event sound entry instead. If the function can find neither the system default entry nor the default sound, it makes no sound and returns FALSE.

Threading

Threading enables your C# program to perform concurrent processing so that you can do more than one operation at a time. For example, you can use threading to monitor input from the user, perform background tasks, and handle simultaneous streams of input. The System.Threading namespace provides classes and interfaces that support multithreaded programming and enable you to easily perform tasks such as creating and starting new threads, synchronizing multiple threads, suspending threads, and aborting threads.

To incorporate threading in your C# code, create a function to be executed outside the main thread and point a new Thread object at it. The following code example creates a new thread in a C# application:

System.Threading.Thread newThread; newThread = new System.Threading.Thread(anObject.AMethod);

The following code example starts a new thread in a C# application:

newThread.Start();

Multithreading solves problems with responsiveness and multi-tasking, but can also introduce resource sharing and synchronization issues because threads are interrupted and resumed without warning according to a central thread that schedules mechanism.

Overview

Threads have the following properties:

· Threads enable your C# program to perform concurrent processing.

· The.NET Framework's System.Threading namespace makes using threads easier.

· Threads share the application's resources.

 


Создание потоков

Потоки позволяют программе C# выполнять параллельную обработку, за счет чего появляется возможность одновременного выполнения нескольких операций. Например, потоки можно использовать для наблюдения ввода данных пользователем, выполнения фоновых задач и обработки одновременных потоков ввода. Пространство имен System.Threading содержит классы и интерфейсы, поддерживающие многопоточное программирование, и позволяет без труда выполнять такие задачи как создание и запуск новых потоков, синхронизация нескольких потоков, приостановка потоков и их отмена.

Чтобы добавить поток в код C#, создайте функцию, которая будет выполняться вне главного потока и укажите в ней новый объект Thread. В следующем примере кода создается новый поток в приложении C#.

System.Threading.Thread newThread; newThread = new System.Threading.Thread(anObject.AMethod);

В следующем примере кода запускается созданный поток в приложении C#.

newThread.Start();

Многопоточность позволяет решить проблемы оперативности и выполнения нескольких задач, но в то же время означает общее использование ресурсов и вызывает проблемы синхронизации из-за прерывания и возобновления потоков без предупреждения в соответствии с центральным потоком, который управляет механизмом.

Общие сведения

Потоки имеют следующие свойства.

· Потоки позволяют программе C# выполнять параллельную обработку.

· Пространство имен.NET Framework System.Threading упрощает использование потоков.

· Потоки используют одни и те же ресурсы приложения.

 


Using Threading

By default, a C# program has one thread. This thread executes the code in the program starting and ending with the Main method. Every command executed by Main--either directly or indirectly--is performed by the default, or primary thread, and this thread terminates when Main returns. However, auxiliary threads can be created and used to execute code in parallel with the primary thread. These threads are often called worker threads.

Worker threads can be used to perform time-consuming or time critical tasks without tying up the primary thread. For example, worker threads are often used in server applications to fulfill incoming requests without waiting for the previous request to be completed. Worker threads are also used to perform "background" tasks in desktop applications so that the main thread--which drives user interface elements--remains responsive to user actions.

Multithreading solves problems with throughput and responsiveness, but it can also introduce resource-sharing issues such as deadlocks and race conditions. Multiple threads are best for tasks that require different resources such as file handles, network connections. Assigning multiple threads to a single resource is likely to cause synchronization issues, and having threads frequently blocked when waiting for other threads defeats the purpose of using multiple threads.

A common strategy is to use worker threads to perform time-consuming or time-critical tasks that do not require many of the resources used by other threads. Naturally, some resources in your program must be accessed by multiple threads. For these cases, the System.Threading namespace provides classes for synchronizing threads. These classes include Mutex, Monitor, Interlocked, and AutoResetEvent, and ManualResetEvent.

You can use some or all these classes to synchronize the activities of multiple threads, but some support for multi-threading is supported by the C# language. For example, the C# Lock Statement provides synchronization features through implicit use of Monitor.

 


Использование потоков

По умолчанию программа на языке C# имеет один поток. Этот поток выполняет код при запуске и завершении программы с помощью метода Main. Каждая команда, выполняемая с помощью метода Main — прямо или косвенно — выполняется по умолчанию или посредством основного потока, и этот поток прекращает работу после возврата Main. Однако параллельно основному потоку могут создаваться и использоваться вспомогательные потоки. Эти потоки часто называются рабочими потоками.

Рабочие потоки могут использоваться для выполнения трудоемких или срочных задач без прерывания основного потока. Например, рабочие потоки часто используются в серверных приложениях для выполнения входящих запросов, не дожидаясь завершения выполнения предыдущего запроса. Рабочие потоки также используются для выполнения "фоновых" задач в настольных приложениях, что позволяет основному потоку (который отвечает за элементы пользовательского интерфейса) оставаться доступным для команд пользователя.

Многопоточность позволяет решить проблемы с пропускной способностью и быстротой ответа системы, однако при этом возникают проблемы совместного использования ресурсов, в частности взаимоблокировки и состояния гонки. Использование нескольких потоков лучше всего подходит для тех задач, которые используют различные ресурсы, например дескрипторы файлов и сетевые подключения. Назначение нескольких потоков одному ресурсу, вероятнее всего, вызовет проблемы синхронизации и частую блокировку потоков во время ожидания, что сведет к минимуму целесообразность использования нескольких потоков.

Обычно рабочие потоки используются для выполнения трудоемких или срочных задач, для которых не требуется большое количество ресурсов, используемых другими потоками. Естественно, некоторые используемые программой ресурсы должны быть доступны для нескольких потоков. В этих случаях пространство имен System.Threading предоставляет классы для синхронизации потоков. Эти классы включают Mutex, Monitor, Interlocked, AutoResetEvent и ManualResetEvent.

Можно использовать некоторые или все эти классы для синхронизации работы нескольких потоков, но некоторые многопоточные функции поддерживаются языком C#. Например, оператор Lock языка C# обеспечивает синхронизацию за счет неявного использования класса Monitor.

 


Thread Synchronization

The following sections describe features and classes that can be used to synchronize access to resources in multithreaded applications.

One of the benefits of using multiple threads in an application is that each thread executes asynchronously. For Windows applications, this allows time-consuming tasks to be performed in the background while the application window and controls remain responsive. For server applications, multithreading provides the ability to handle each incoming request with a different thread. Otherwise, each new request would not get serviced until the previous request had been fully satisfied.

However, the asynchronous nature of threads means that access to resources such as file handles, network connections, and memory must be coordinated. Otherwise, two or more threads could access the same resource at the same time, each unaware of the other's actions. The result is unpredictable data corruption.

For simple operations on integral numeric data types, synchronizing threads can be accomplished with members of the Interlocked class. For all other data types and non thread-safe resources, multithreading can only be safely performed using the constructs in this topic.

The lock Keyword

The lock keyword can be used to ensure that a block of code runs to completion without interruption by other threads. This is accomplished by obtaining a mutual-exclusion lock for a given object for the duration of the code block.

A lock statement begins with the keyword lock, which is given an object as an argument, and followed by a code block that is to be executed by only one thread at a time. For example:

public class TestThreading { private System.Object lockThis = new System.Object();   public void Function() {   lock (lockThis) { // Access thread-sensitive resources. } } }

Синхронизация потоков

В следующих разделах описаны функции и классы, которые можно использовать для синхронизации доступа к ресурсам в многопоточных приложениях.

Одним из преимуществ использования нескольких потоков в приложении является асинхронное выполнение каждого потока. В приложениях Windows это позволяет выполнять длительные задачи в фоновом режиме, при этом окно приложения и элементы управления остаются активными. Для серверных приложений многопоточность обеспечивает возможность обработки каждого входящего запроса в отдельном потоке. В противном случае ни один новый запрос не будет обработан, пока не завершена обработка предыдущего запроса.

Однако вследствие того, что потоки асинхронные, доступ к ресурсам, таким как дескрипторы файлов, сетевые подключения и память, должен быть скоординирован. Иначе два или более потоков могут получить доступ к одному и тому же ресурсу одновременно, причем один поток не будет учитывать действия другого. В результате данные могут быть повреждены непредсказуемым образом.

Для простых операций над числовыми типами данных синхронизация потоков выполняется с помощью членов класса Interlocked. Для прочих типов данных и других ресурсов, не являющихся потокобезопасными, многопоточность можно применять только с помощью структур, описываемых в этом разделе.

Ключевое слово lock

Ключевое слово lock используется для того, чтобы выполнение блока кода не прерывалось кодом, выполняемым в других потоках. Для этого нужно получить взаимоисключающую блокировку для данного объекта на время длительности блока кода.

Оператор lock начинается с ключевого слова lock, которому в качестве аргумента указывается объект, и за которым следует блок кода, который должен выполняться одновременно только в одном потоке. Пример.

ß--

 


The argument provided to the lock keyword must be an object based on a reference type, and is used to define the scope of the lock. In the example above, the lock scope is limited to this function because no references to the object exist outside the function. If such a reference did exist, lock scope would extend to that object. Strictly speaking, the object provided to lock is used solely to uniquely identify the resource being shared among multiple threads, so it can be an arbitrary class instance. In practice, however, this object usually represents the resource for which thread synchronization is necessary. For example, if a container object is to be used by multiple threads, then the container can be passed to lock, and the synchronized code block following the lock would access the container. As long as other threads locks on the same contain before accessing it, then access to the object is safely synchronized.

Generally, it is best to avoid locking on a public type, or on object instances beyond the control of your application. For example, lock(this) can be problematic if the instance can be accessed publicly, because code beyond your control may lock on the object as well. This could create deadlock situations where two or more threads wait for the release of the same object. Locking on a public data type, as opposed to an object, can cause problems for the same reason. Locking on literal strings is especially risky because literal strings are interned by the common language runtime (CLR). This means that there is one instance of any given string literal for the entire program, the exact same object represents the literal in all running application domains, on all threads. As a result, a lock placed on a string with the same contents anywhere in the application process locks all instances of that string in the application. As a result, it is best to lock a private or protected member that is not interned. Some classes provide members specifically for locking. The Array type, for example, provides SyncRoot. Many collection types provide a SyncRoot member as well.

 


Аргумент, предоставляемый ключевому слову lock, должен быть объектом на основе ссылочного типа; он используется для определения области блокировки. В приведенном выше примере область блокировки ограничена этой функцией, поскольку не существует ссылок на объект вне функции. Если бы такая ссылка существовала, область блокировки включала бы этот объект. Строго говоря, объект, предоставляемый для lock, используется только для того, чтобы уникальным образом определить ресурс, к которому предоставляется доступ для различных потоков, поэтому это может быть произвольный экземпляр класса. В действительности этот объект обычно представляет ресурс, для которого требуется синхронизация потоков. Например, если объект контейнера должен использоваться в нескольких потоках, то контейнер можно передать блокировке, а блок синхронизированного кода после блокировки должен получить доступ к контейнеру. Если другие потоки блокируются для того же контейнера перед доступом к нему, обеспечивается безопасная синхронизация доступа к объекту.

Как правило, рекомендуется избегать блокировки типа public или экземпляров объектов, которыми не управляет код вашего приложения. Например, использование lock(this) может привести к неполадкам, если к экземпляру разрешен открытый доступ, поскольку внешний код также может блокировать объект. Это может привести к созданию ситуаций взаимной блокировки, когда два или несколько потоков будут ожидать высвобождения одного и того же объекта. По этой же причине блокировка открытого типа данных (в отличие от объектов) может привести к неполадкам. Блокировка строковых литералов наиболее опасна, поскольку строковые литералы интернируются средой CLR. Это означает, что если во всей программе есть один экземпляр любого строкового литерала, точно такой же объект будет представлять литерал во всех запущенных доменах приложения и во всех потоках. В результате блокировка, включенная для строки с одинаковым содержимым во всем приложении, блокирует все экземпляры этой строки в приложении. По этой причине лучше использовать блокировку закрытых или защищенных членов, для которых интернирование не применяется. В некоторых классах есть члены, специально предназначенные для блокировки. Например, в типе Array есть SyncRoot. Во многих типах коллекций есть член SyncRoot.

 


Monitors

Like the lock keyword, monitors prevent blocks of code from simultaneous execution by multiple threads. The Enter method allows one and only one thread to proceed into the following statements; all other threads are blocked until the executing thread calls Exit. This is just like using the lock keyword. In fact, the lock keyword is implemented with the Monitor class. For example:

lock (x) { DoSomething(); }

This is equivalent to:

System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); try { DoSomething(); } finally { System.Threading.Monitor.Exit(obj); }

Using the lock keyword is generally preferred over using the Monitor class directly, both because lock is more concise, and because lock insures that the underlying monitor is released, even if the protected code throws an exception. This is accomplished with the finally keyword, which executes its associated code block regardless of whether an exception is thrown.

 


Мониторы

Как и lock, мониторы не допускают одновременное выполнение несколькими потоками одних и тех не блоков кода. Метод Enter позволяет только одному методу переходить к последующим операторам, все прочие методы заблокированы, пока выполняемый метод не вызовет Exit. Это аналогично использованию ключевого слова lock. Ключевое слово lock реализовано с классом Monitor. Пример.

lock (x) { DoSomething(); }

Соответствует следующему:

System.Object obj = (System.Object)x; System.Threading.Monitor.Enter(obj); try { DoSomething(); } finally { System.Threading.Monitor.Exit(obj); }

Рекомендуется использовать ключевое слово lock, а не класс Monitor, поскольку lock компактнее и потому что lock обеспечивает высвобождение монитора даже если защищенный код создал исключение. Для этого применяется ключевое слово finally, которые выполняет свой блок кода вне зависимости от наличия исключений.

 



Поделиться:


Последнее изменение этой страницы: 2017-01-19; просмотров: 102; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.219.95.244 (0.04 с.)